En esta página, se describe cómo encontrar vecinos más cercanos aproximados (ANN) y consultar incorporaciones de vectores con las funciones de distancia de ANN.
Cuando un conjunto de datos es pequeño, puedes usar el algoritmo de k-vecinos más cercanos (KNN) para encontrar los vectores k-más cercanos exactos. Sin embargo, a medida que crece tu conjunto de datos, también aumentan la latencia y el costo de una búsqueda de KNN. Puedes usar el ANN para encontrar los k vecinos más cercanos aproximados con una latencia y un costo significativamente reducidos.
En una búsqueda de ANN, los vectores k devueltos no son los k vecinos más cercanos verdaderos porque la búsqueda de ANN calcula distancias aproximadas y es posible que no considere todos los vectores del conjunto de datos. En ocasiones, se muestran algunos vectores que no se encuentran entre los k vecinos más cercanos. Esto se conoce como pérdida de recuperación. La cantidad de pérdida de recuperación que es aceptable para ti depende del caso de uso, pero, en la mayoría de los casos, perder un poco de recuperación a cambio de un mejor rendimiento de la base de datos es una compensación aceptable.
Para obtener más detalles sobre las funciones de distancia aproximada compatibles con Spanner, consulta las siguientes páginas de referencia para tu dialecto de base de datos:
- GoogleSQL
- PostgreSQL
Consulta embeddings de vectores
Spanner acelera las búsquedas de vectores de vecino más cercano aproximado (ANN) con un índice de vectores. Puedes usar un índice de vectores para consultar embeddings de vectores. Para consultar embeddings de vectores, primero debes crear un índice de vectores. Luego, puedes usar cualquiera de las tres funciones de distancia aproximada para encontrar el ANN.
Las restricciones cuando se usan las funciones de distancia aproximada incluyen lo siguiente:
- La función de distancia aproximada debe calcular la distancia entre una columna de incorporación y una expresión constante (por ejemplo, un parámetro o un literal).
- El resultado de la función de distancia aproximada se debe usar en una cláusula
ORDER BYcomo la única clave de ordenamiento, y se debe especificar unLIMITdespués delORDER BY. - La consulta debe filtrar de forma explícita las filas que no están indexadas. En la mayoría de los casos, esto significa que la consulta debe incluir una cláusula
WHERE <column_name> IS NOT NULLque coincida con la definición del índice de vectores, a menos que la columna ya esté marcada comoNOT NULLen la definición de la tabla.
Para obtener una lista detallada de las limitaciones, consulta la página de referencia de la función de distancia aproximada.
Ejemplos
Considera una tabla Documents que tiene una columna DocEmbedding de embeddings de texto precalculados de la columna de bytes DocContents y una columna NullableDocEmbedding propagada desde otras fuentes que podrían ser nulas.
GoogleSQL
CREATE TABLE Documents (
UserId INT64 NOT NULL,
DocId INT64 NOT NULL,
Author STRING(1024),
DocContents BYTES(MAX),
DocEmbedding ARRAY<FLOAT32> NOT NULL,
NullableDocEmbedding ARRAY<FLOAT32>,
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[] not null,
nullable_doc_embedding float4[],
word_count bigint,
PRIMARY KEY (user_id, doc_id)
);
Para buscar los 100 vectores más cercanos a [1.0, 2.0, 3.0], haz lo siguiente:
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;
Para buscar los 100 vectores más cercanos a un embedding que se genera con una expresión SQL, usa el siguiente patrón. En este ejemplo, la consulta busca los documentos más similares a la incorporación de UserId = 1 y 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 columna de embedding admite valores nulos, haz lo siguiente:
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;
Agrega la distancia a los resultados de la búsqueda
En los ejemplos anteriores, la distancia de ANN se usa para ordenar los resultados de la búsqueda, pero no se muestra en esos resultados. Para agregar la distancia a los resultados, coloca la función de distancia en la cláusula SELECT y asígnale un alias. Luego, usa ese alias como la única clave de ordenamiento en la cláusula ORDER BY.
Ejemplos
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;
¿Qué sigue?
Obtén más información sobre los índices de vectores de Spanner.
Obtén más información sobre las funciones de distancia aproximada en GoogleSQL y PostgreSQL.
Obtén más información sobre las instrucciones de índice para GoogleSQL
VECTOR INDEXy PostgreSQLINDEX.Obtén más información sobre las prácticas recomendadas para los índices vectoriales.
Prueba el instructivo Primeros pasos con la búsqueda de vectores de Spanner para ver un ejemplo paso a paso del uso de la ANN.