L'extension pg_textsearch dans Cloud SQL pour PostgreSQL fournit une recherche en texte intégral à l'aide de l'algorithme de scoring BM25 (Best Matching 25), une norme du secteur, pour fournir un score de pertinence très précis. L'extension est un projet Open Source disponible sur GitHub.
L'extension pg_textsearch nécessite PostgreSQL 17 ou version ultérieure.
Comme pg_textsearch est compatible avec la fréquence inverse du document, la saturation de la fréquence des termes et la normalisation de la longueur du document, il peut produire des résultats plus pertinents que la fonction ts_rank intégrée de PostgreSQL. De plus, comme il fonctionne directement sur les pages de stockage PostgreSQL standards, vous n'avez pas besoin d'installer un moteur externe comme Elasticsearch ni de vous soucier de la maintenance des doubles clusters et de la synchronisation des données. À l'aide de pg_textsearch, vous pouvez créer des expériences de recherche robustes, évolutives et très pertinentes sans quitter l'écosystème PostgreSQL.
Différentes façons de faire des recherches
Plusieurs options de recherche de texte sont disponibles dans Cloud SQL pour PostgreSQL :
Correspondance exacte : avec la recherche SQL standard, vous utilisez les instructions
LIKEetILIKEpour rechercher une séquence exacte de caractères. Par exemple, la requêteILIKE '%smart fitness watches%'permet de trouver des instances telles que :- "Découvrez nos nouvelles montres connectées pour la forme en promotion."
- "Les montres connectées pour la forme sont d'excellents cadeaux."
Toutefois, il ne trouverait pas :
- "Les coureurs veulent une montre de fitness intelligente et étanche."
- "Cette montre est particulièrement intelligente en matière de remise en forme."
Recherche en texte intégral : à l'aide de l'algorithme BM25 et de
tsvector, la recherche en texte intégral divise le texte en mots racines, ignore les mots filtres et évalue la pertinence. Elle comprend les règles linguistiques, y compris le pluriel et la grammaire, et tient compte de la fréquence des mots. Une recherche en texte intégral poursmart AND fitness AND watchestrouverait les instances que la requête de correspondance exacte de l'exemple manquerait, ainsi que des instances plus complexes comme celles-ci :- "Une montre connectée est idéale pour votre routine sportive quotidienne."
- "Toutes les montres ne sont pas aussi intelligentes en matière de forme physique."
Toutefois, il ne trouverait pas :
- "Une montre intelligente qui tient compte de votre santé peut vous aider dans votre programme d'exercice."
- "Ce bracelet intelligent de suivi d'activité est une aubaine."
Recherche sémantique : à l'aide de modèles d'IA, la recherche sémantique convertit le texte en vecteurs et mesure la distance de similarité. Il comprend la signification, l'intention, le contexte, les synonymes et les concepts associés. Une recherche sémantique pour
smart fitness watchestrouverait les exemples d'instances que les autres méthodes de recherche manqueraient. Elle comprendrait qu'une "montre intelligente axée sur la santé" est la même chose qu'une "montre de fitness intelligente", et qu'un "bracelet intelligent de suivi d'activité physique" pourrait également être pertinent. Il peut s'agir d'une erreur de correspondance avec un bracelet podomètre si la priorité n'a pas été suffisamment accordée à "montre".
Installer l'extension pg_textsearch
Pour installer et activer pg_textsearch, procédez comme suit :
Définissez le flag
cloudsql.enable_pg_textsearchsuron, comme décrit dans Configurer des options de base de données. Cela ajoutepg_textsearchàshared_preload_libraries.Installer l'extension
pg_textsearchCREATE EXTENSION pg_textsearch;Vérifiez l'installation :
SELECT extversion FROM pg_extension WHERE extname = 'pg_textsearch'
Rechercher avec pg_textsearch
Supposons que l'exemple de tableau suivant ait été rempli avec des données :
CREATE TABLE documents (
doc_id TEXT PRIMARY KEY,
content TEXT,
text_embedding vector(3072)
GENERATED ALWAYS AS (embedding('gemini-embedding-001', content)) STORED
);
Avant d'utiliser la recherche en texte intégral, créez d'abord un index BM25 :
CREATE INDEX idx_docs_bm25
ON documents
USING bm25 (content)
WITH (text_config = 'english');
Vous pouvez ensuite effectuer une requête de recherche en texte intégral comme suit :
SELECT doc_id, content, content <@> 'database system'
AS score FROM documents
ORDER BY content <@> 'database system'
ASC LIMIT 5;
Effectuer des recherches hybrides à l'aide de pg_textsearch et vector
Vous pouvez utiliser pg_textsearch avec l'extension de recherche sémantique vector pour effectuer des recherches hybrides. Installez l'extension de recherche sémantique vector comme suit :
CREATE EXTENSION IF NOT EXISTS vector CASCADE;
Effectuez une requête de recherche hybride sémantique et en texte intégral comme celle-ci :
WITH
-- Semantic search results
vector_search AS (
SELECT doc_id,
RANK () OVER (ORDER BY text_embedding <=>
google_ml.embedding('gemini-embedding-001',
'database')::VECTOR ) AS rank
FROM documents
ORDER BY text_embedding <=> google_ml.embedding('gemini-embedding-001',
'database')::VECTOR
LIMIT 10
),
-- Full text search results
text_search AS (
SELECT doc_id,
RANK () OVER (ORDER BY content <@> 'database' ASC) AS rank
FROM documents
ORDER BY content <@> 'database' ASC
LIMIT 10
)
-- RRF combining both semantic and full text search results
SELECT
COALESCE(vector_search.doc_id, text_search.doc_id) AS id,
COALESCE(1.0 / (60 + vector_search.rank), 0.0) +
COALESCE(1.0 / (60 + text_search.rank), 0.0) AS rrf_score
FROM vector_search
FULL OUTER JOIN text_search ON vector_search.doc_id = text_search.doc_id
ORDER BY rrf_score DESC
LIMIT 5;
Indicateurs pour configurer l'extension pg_textsearch
Utilisez les flags suivants pour configurer la recherche en texte intégral pg_textsearch :
pg_textsearch.bulk_load_threshold: termes par transaction avant le déversement automatique. Définissez la valeur sur 0 pour désactiver la fonctionnalité. Valeur par défaut : 100 000.pg_textsearch.compress_segments: compresse les blocs de publication dans les nouveaux segments. Valeur par défaut :onpg_textsearch.default_limit: nombre maximal de documents évalués lorsqu'aucune clauseLIMITn'est présente. Par défaut : 1 000.pg_textsearch.memtable_pages_threshold: nombre de pages à enchaîner avant le déversement automatique. Définissez la valeur sur 0 pour désactiver la fonctionnalité. Valeur par défaut : 64.pg_textsearch.segments_per_level: nombre de segments par niveau avant la compaction automatique. Plage : 2 à 64. Valeur par défaut : 8.