Cette page explique comment trouver les plus proches voisins approximatifs (ANN) et interroger les embeddings vectoriels à l'aide des fonctions de distance ANN.
Lorsqu'un ensemble de données est petit, vous pouvez utiliser les k plus proches voisins (KNN) pour trouver les k vecteurs les plus proches exacts. Cependant, à mesure que votre ensemble de données s'agrandit, la latence et le coût d'une recherche KNN augmentent également. Vous pouvez utiliser l'ANN pour trouver les k éléments voisins les plus proches approximatifs avec une latence et un coût considérablement réduits.
Dans une recherche ANN, les k vecteurs renvoyés ne sont pas les k voisins les plus proches, car la recherche ANN calcule des distances approximatives et peut ne pas examiner tous les vecteurs de l'ensemble de données. Il arrive que quelques vecteurs qui ne font pas partie des k plus proches voisins soient renvoyés. C'est ce qu'on appelle la perte de rappel. La perte de rappel acceptable dépend du cas d'utilisation, mais dans la plupart des cas, perdre un peu de rappel en échange d'une amélioration des performances de la base de données est un compromis acceptable.
Pour en savoir plus sur les fonctions de distance approximative compatibles avec Spanner, consultez les pages de référence suivantes pour votre dialecte de base de données :
- GoogleSQL
- PostgreSQL
Interroger les embeddings vectoriels
Spanner accélère les recherches vectorielles des plus proches voisins approximatifs (ANN) en utilisant un index vectoriel. Vous pouvez utiliser un index vectoriel pour interroger des embeddings vectoriels. Pour interroger des embeddings vectoriels, vous devez d'abord créer un index vectoriel. Vous pouvez ensuite utiliser l'une des trois fonctions de distance approximative pour trouver les plus proches voisins approximatifs.
Les restrictions suivantes s'appliquent lors de l'utilisation des fonctions de distance approximative :
- La fonction de distance approximative doit calculer la distance entre une colonne d'embedding et une expression constante (par exemple, un paramètre ou un littéral).
- Le résultat de la fonction de distance approximative doit être utilisé dans une clause
ORDER BYcomme seule clé de tri, et une clauseLIMITdoit être spécifiée après la clauseORDER BY. - La requête doit explicitement filtrer les lignes qui ne sont pas indexées. Dans la plupart des cas, cela signifie que la requête doit inclure une clause
WHERE <column_name> IS NOT NULLcorrespondant à la définition de l'index vectoriel, sauf si la colonne est déjà marquée commeNOT NULLdans la définition de la table.
Pour obtenir la liste détaillée des limites, consultez la page de référence sur la fonction de distance approximative.
Exemples
Prenons l'exemple d'une table Documents qui comporte une colonne DocEmbedding d'embeddings textuels précalculés à partir de la colonne d'octets DocContents, et une colonne NullableDocEmbedding renseignée à partir d'autres sources qui peuvent être nulles.
Les deux colonnes d'embedding spécifient une longueur de vecteur de 3, ce qui est nécessaire pour créer un index vectoriel pour la recherche ANN.
GoogleSQL
CREATE TABLE Documents (
UserId INT64 NOT NULL,
DocId INT64 NOT NULL,
Author STRING(1024),
DocContents BYTES(MAX),
DocEmbedding ARRAY<FLOAT32>(vector_length=>3) NOT NULL,
NullableDocEmbedding ARRAY<FLOAT32>(vector_length=>3),
WordCount INT64
) PRIMARY KEY (UserId, DocId);
PostgreSQL
CREATE TABLE documents (
user_id bigint not null,
doc_id bigint not null,
author varchar(1024),
doc_contents bytea,
doc_embedding float4[] VECTOR LENGTH 3 not null,
nullable_doc_embedding float4[] VECTOR LENGTH 3,
word_count bigint,
PRIMARY KEY (user_id, doc_id)
);
Pour rechercher les 100 vecteurs les plus proches de [1.0, 2.0, 3.0], spécifiez l'une des options de recherche suivantes dans la fonction de distance approximative :
num_leaves_to_search: nombre de feuilles à rechercher. La valeur doit être un entier positif.pct_leaves_to_search: pourcentage de feuilles à rechercher. La valeur doit être un double compris entre0.0et100.0avec un séparateur décimal explicite (par exemple,10.0). Les index vectoriels créés avant novembre 2025 peuvent ne pas être compatibles avec cette option de recherche.
Vous ne pouvez pas spécifier les deux options dans la même fonction de distance approximative.
Option 1. Utiliser l'option de recherche num_leaves_to_search
GoogleSQL
SELECT DocId
FROM Documents
WHERE WordCount > 1000
ORDER BY APPROX_EUCLIDEAN_DISTANCE(
ARRAY<FLOAT32>[1.0, 2.0, 3.0], DocEmbedding,
options => JSON '{"num_leaves_to_search": 10}')
LIMIT 100
PostgreSQL
SELECT doc_id
FROM documents
WHERE word_count > 1000
ORDER BY spanner.approx_euclidean_distance(
ARRAY[1.0, 2.0, 3.0]::float4[], doc_embedding,
options=>jsonb'{"num_leaves_to_search": 10}'
)
LIMIT 100;
Option 2. Utiliser l'option de recherche pct_leaves_to_search
GoogleSQL
SELECT DocId
FROM Documents
WHERE WordCount > 1000
ORDER BY APPROX_EUCLIDEAN_DISTANCE(
ARRAY<FLOAT32>[1.0, 2.0, 3.0], DocEmbedding,
options => JSON '{"pct_leaves_to_search": 10.0}')
LIMIT 100
PostgreSQL
SELECT doc_id
FROM documents
WHERE word_count > 1000
ORDER BY spanner.approx_euclidean_distance(
ARRAY[1.0, 2.0, 3.0]::float4[], doc_embedding,
options=>jsonb'{"pct_leaves_to_search": 10.0}'
)
LIMIT 100;
Pour rechercher les 100 vecteurs les plus proches d'un embedding généré par une expression SQL, utilisez le modèle suivant. Dans cet exemple, la requête recherche les documents les plus semblables à l'embedding de UserId = 1 et DocId = 1 :
GoogleSQL
WITH emb AS (
SELECT DocEmbedding AS value
FROM Documents
WHERE UserId = 1 AND DocId = 1
LIMIT 1
)
SELECT DocId
FROM Documents, emb
ORDER BY APPROX_EUCLIDEAN_DISTANCE(
emb.value, DocEmbedding,
options => JSON '{"num_leaves_to_search": 10}')
LIMIT 100
PostgreSQL
SELECT documents.doc_id
FROM
documents,
(
SELECT doc_embedding AS value
FROM documents
WHERE user_id = 1 AND doc_id = 1
LIMIT 1
) vector
WHERE documents.doc_embedding IS NOT NULL
ORDER BY spanner.APPROX_EUCLIDEAN_DISTANCE(documents.doc_embedding,
vector.value, options=>'{"num_leaves_to_search": 10}'::jsonb)
LIMIT 100
Si la colonne d'embeddings peut avoir une valeur nulle :
GoogleSQL
SELECT DocId
FROM Documents
WHERE NullableDocEmbedding IS NOT NULL AND WordCount > 1000
ORDER BY APPROX_EUCLIDEAN_DISTANCE(
ARRAY<FLOAT32>[1.0, 2.0, 3.0], NullableDocEmbedding,
options => JSON '{"num_leaves_to_search": 10}')
LIMIT 100
PostgreSQL
SELECT doc_id
FROM documents
WHERE nullable_doc_embedding IS NOT NULL AND word_count > 1000
ORDER BY spanner.approx_euclidean_distance(
ARRAY[1.0, 2.0, 3.0]::float4[], nullable_doc_embedding,
options=>jsonb'{"num_leaves_to_search": 10}'
)
LIMIT 100;
Ajouter la distance aux résultats de la requête
Dans les exemples précédents, la distance ANN est utilisée pour trier les résultats de la requête, mais elle n'est pas affichée dans ces résultats. Pour ajouter la distance aux résultats, placez la fonction de distance dans la clause SELECT et attribuez-lui un alias, puis utilisez cet alias comme seule clé de tri dans la clause ORDER BY.
Exemples
GoogleSQL
SELECT DocId,
APPROX_EUCLIDEAN_DISTANCE(
ARRAY<FLOAT32>[1.0, 2.0, 3.0], NullableDocEmbedding,
options => JSON '{"num_leaves_to_search": 10}') AS distance
FROM Documents
WHERE NullableDocEmbedding IS NOT NULL AND WordCount > 1000
ORDER BY distance
LIMIT 100
PostgreSQL
SELECT doc_id,
spanner.approx_euclidean_distance(
ARRAY[1.0, 2.0, 3.0]::float4[], nullable_doc_embedding,
options=>jsonb'{"num_leaves_to_search": 10}'
) AS distance
FROM documents
WHERE nullable_doc_embedding IS NOT NULL AND word_count > 1000
ORDER BY distance
LIMIT 100;
Étapes suivantes
En savoir plus sur les index vectoriels Spanner
En savoir plus sur les fonctions de distance approximative dans GoogleSQL et PostgreSQL.
En savoir plus sur les instructions d'index pour GoogleSQL
VECTOR INDEXet PostgreSQLINDEX.En savoir plus sur les bonnes pratiques concernant les index vectoriels
Consultez Premiers pas avec la recherche vectorielle Spanner pour obtenir un exemple d'utilisation de l'ANN étape par étape.