Ce document explique comment effectuer des recherches hybrides dans AlloyDB pour PostgreSQL, qui combine la recherche de texte, la correspondance des mots clés, la recherche vectorielle et la similarité sémantique à l'aide de l'extension vector
, qui est une extension pgvector
PostgreSQL standard personnalisée pour AlloyDB. La recherche hybride vous permet de récupérer des résultats très pertinents en utilisant à la fois des correspondances exactes de mots clés et du contenu sémantiquement similaire.
Exécuter une recherche de similarité avec une entrée textuelle et vectorielle
Pour effectuer une recherche hybride dans AlloyDB pour PostgreSQL, vous devez créer un index vectoriel et un index de recherche textuelle dans votre table. Vous combinerez ensuite les résultats des deux recherches et les reclasserez de manière à présenter les informations les plus pertinentes.
Créer un index GIN
Un index GIN (Generalized Inverted Index) est un type d'index spécialisé optimisé pour la recherche dans des valeurs composites, telles que les tableaux, les données JSONB et les données de recherche en texte intégral.
Pour créer un index GIN sur vos données textuelles afin d'effectuer une recherche en texte intégral, exécutez la commande suivante :
CREATE INDEX INDEX_NAME ON TABLE USING GIN (to_tsvector('english', COLUMN_NAME));
Remplacez les éléments suivants :
INDEX_NAME
: nom de l'index que vous souhaitez créer, par exemplemy-gin-index
.TABLE
: table à laquelle ajouter l'index.COLUMN_NAME
: colonne qui stocke les données textuelles que vous souhaitez rechercher.
Créer un index ScaNN
Pour appliquer un index arborescent à deux niveaux à l'aide de l'algorithme ScaNN à une colonne contenant des embeddings vectoriels stockés, exécutez la requête LDD suivante :
CREATE INDEX INDEX_NAME ON TABLE
USING scann (EMBEDDING_COLUMN DISTANCE_FUNCTION)
WITH (num_leaves=NUM_LEAVES_VALUE);
Remplacez les éléments suivants :
INDEX_NAME
: nom de l'index que vous souhaitez créer, par exemplemy-scann-index
. Les noms d'index sont partagés dans votre base de données. Assurez-vous que chaque nom d'index est unique pour chaque table de votre base de données.TABLE
: table à laquelle ajouter l'index.EMBEDDING_COLUMN
: colonne qui stocke les donnéesvector
.DISTANCE_FUNCTION
: fonction de distance à utiliser avec cet index. Choisissez l'une des options suivantes :Distance L2 :
l2
Produit scalaire :
dot_product
Distance de cosinus :
cosine
NUM_LEAVES_VALUE
: nombre de partitions à appliquer à cet index. Définissez une valeur comprise entre 1 et 1 048 576. Pour savoir comment déterminer cette valeur, consultez Régler un indexScaNN
.
Pour en savoir plus sur les différentes configurations d'index ScaNN, consultez Créer un index ScaNN
. Vous pouvez également créer un index HNSW.
Effectuer une recherche hybride à l'aide de la fusion de classement réciproque
La recherche hybride consiste à effectuer des recherches vectorielles et textuelles distinctes, puis à combiner et reclasser les résultats à l'aide de la fusion de classement réciproque (RRF). La RRF est un algorithme basé sur le classement qui combine plusieurs listes classées de résultats de recherche en une seule liste classée en attribuant un score à chaque document. Ce score est basé sur le classement réciproque du RRF dans toutes les listes contributrices. Les documents les mieux classés bénéficient d'une contribution plus importante. Utilisez la requête SQL suivante pour combiner la recherche en texte intégral et la recherche hybride, et reclasser les résultats :
WITH vector_search AS (
SELECT id,
RANK () OVER (ORDER BY embedding <=> google_ml.embedding('MODEL_ID', 'TEXT')) AS rank
FROM TABLE
ORDER BY embedding <=> google_ml.embedding('MODEL_ID', 'TEXT') LIMIT 10
),
text_search AS (
SELECT id,
RANK () OVER (ORDER BY ts_rank(to_tsvector('english', COLUMN_NAME), to_tsquery(KEYWORD)) desc)
FROM TABLE
WHERE to_tsvector('english', COLUMN_NAME) @@ to_tsquery(KEYWORD)
ORDER BY ts_rank(to_tsvector('english', COLUMN_NAME), to_tsquery(KEYWORD)) desc
LIMIT 10
)
SELECT
COALESCE(vector_search.id, text_search.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.id = text_search.id
ORDER BY rrf_score DESC
LIMIT 5;
Remplacez les éléments suivants :
MODEL_ID
: ID du modèle à interroger.Si vous utilisez Vertex AI Model Garden, spécifiez
text-embedding-005
comme ID de modèle. Il s'agit des modèles cloud qu'AlloyDB peut utiliser pour les embeddings textuels. Pour en savoir plus, consultez Embeddings textuels.TABLE
: table contenant vos données.TEXT
: texte à traduire en embedding vectoriel.KEYWORD
: mot clé que vous souhaitez rechercher.COLUMN_NAME
: colonne qui stocke les données textuelles que vous souhaitez rechercher.
Explication de la requête de recherche hybride et de l'expression de table commune (CTE) associée :
- CTE
vector_search
: effectue une recherche de similarité vectorielle standard, en classant les résultats par distance de cosinus et en leur attribuant un classement. Elle récupère les 10 produits les plus similaires d'un point de vue sémantique. - CTE
text_search
: exécute une recherche textuelle à l'aide deto_tsvector
etto_tsquery
, calcule la pertinence avects_rank
et récupère les 10 correspondances textuelles les plus pertinentes. - CTE
Final SELECT Statement
: joint les résultats des recherches vectorielle et textuelle à l'aide d'unFULL OUTER JOIN
, sélectionne l'ID du produit, calcule le score RRF, trie les résultats par score et récupère les cinq premiers résultats.