Realizar pesquisa de similaridade vetorial no Spanner encontrando os vizinhos mais próximos K
Mantenha tudo organizado com as coleções
Salve e categorize o conteúdo com base nas suas preferências.
Esta página descreve como realizar uma pesquisa de similaridade de vetor no Spanner usando as funções de vetor de distância de cosseno, distância euclidiana e produto escalar para encontrar os K vizinhos mais próximos. Essas informações se aplicam a bancos de dados do dialeto GoogleSQL e do dialeto PostgreSQL. Antes de ler esta página,
é importante entender os seguintes conceitos:
Produto escalar: calcula o cosseno do ângulo multiplicado pelo produto das magnitudes dos vetores correspondentes. Se você souber que todos os embeddings de vetor no seu conjunto de dados estão normalizados, poderá usar DOT_PRODUCT() como uma função de distância.
Vizinhos k-mais próximos (KNN): um algoritmo de aprendizado de máquina supervisionado usado para resolver problemas de classificação ou regressão.
Você pode usar funções de distância vetorial para realizar uma pesquisa de vetor de vizinhos mais próximos (KNN) em casos de uso como pesquisa por similaridade ou geração aumentada de recuperação. O Spanner é compatível com as funções COSINE_DISTANCE(), EUCLIDEAN_DISTANCE() e DOT_PRODUCT(), que operam em embeddings de vetor, permitindo encontrar o KNN do embedding de entrada.
Por exemplo, depois de gerar e salvar seus dados operacionais do Spanner como embeddings de vetor, você pode fornecer esses embeddings como um parâmetro de entrada na sua consulta para encontrar os vetores mais próximos no espaço N-dimensional e pesquisar itens semanticamente semelhantes ou relacionados.
Todas as três funções de distância usam os argumentos vector1 e vector2, que são do tipo array<> e precisam consistir nas mesmas dimensões e ter o mesmo comprimento. Para mais detalhes sobre essas funções, consulte:
Os exemplos a seguir mostram a pesquisa de KNN, a pesquisa de KNN em dados particionados e o uso de um índice secundário com KNN.
Todos os exemplos usam EUCLIDEAN_DISTANCE(). Também é possível usar
COSINE_DISTANCE(). Além disso, se todos os embeddings de vetor no seu conjunto de dados estiverem normalizados, você poderá usar DOT_PRODUCT() como uma função de distância.
Exemplo 1: pesquisa de vizinho k-mais perto
Considere uma tabela Documents que tem uma coluna (DocEmbedding) de incorporações de texto pré-computadas da coluna de bytes DocContents.
Supondo que um embedding de entrada para "beisebol, mas não beisebol profissional" seja a matriz [0.3, 0.3, 0.7, 0.7], você pode encontrar os cinco documentos mais próximos que correspondem com a seguinte consulta:
A consulta no exemplo anterior pode ser modificada adicionando condições à cláusula WHERE para limitar a pesquisa vetorial a um subconjunto dos seus dados. Uma aplicação comum disso é pesquisar dados particionados, como linhas que pertencem a um UserId específico.
Exemplo 3: pesquisa de KNN em intervalos de índice secundário
Se o filtro de cláusula WHERE que você está usando não fizer parte da chave primária da tabela, crie um índice secundário para acelerar a operação com uma verificação somente de índice.
GoogleSQL
CREATEINDEXDocsByAuthorONDocuments(Author)STORING(DocEmbedding);SELECTAuthor,DocId,DocEmbeddingFROMDocumentsWHEREAuthor="Mark Twain"ORDERBYEUCLIDEAN_DISTANCE(DocEmbedding,<embeddingsfor"book about the time traveling American">)LIMIT5;
PostgreSQL
CREATEINDEXDocsByAuthorONDocuments(Author)INCLUDE(DocEmbedding);SELECTAuthor,DocId,DocEmbeddingFROMDocumentsWHEREAuthor="Mark Twain"ORDERBYspanner.euclidean_distance(DocEmbedding,<embeddingsfor"that book about the time traveling American">)LIMIT5;
[[["Fácil de entender","easyToUnderstand","thumb-up"],["Meu problema foi resolvido","solvedMyProblem","thumb-up"],["Outro","otherUp","thumb-up"]],[["Difícil de entender","hardToUnderstand","thumb-down"],["Informações incorretas ou exemplo de código","incorrectInformationOrSampleCode","thumb-down"],["Não contém as informações/amostras de que eu preciso","missingTheInformationSamplesINeed","thumb-down"],["Problema na tradução","translationIssue","thumb-down"],["Outro","otherDown","thumb-down"]],["Última atualização 2025-08-11 UTC."],[],[],null,["# Perform vector similarity search in Spanner by finding the K-nearest neighbors\n\n| **Note:** This feature is available with the Spanner Enterprise edition and Enterprise Plus edition. For more information, see the [Spanner editions overview](/spanner/docs/editions-overview).\n\n\u003cbr /\u003e\n\nThis page describes how to perform a vector similarity search in\nSpanner by using the cosine distance, Euclidean distance, and dot\nproduct vector functions to find K-nearest neighbors. This information\napplies to both GoogleSQL-dialect databases and PostgreSQL-dialect databases. Before you read this page,\nit's important that you understand the following concepts:\n\n- [Euclidean distance](https://en.wikipedia.org/wiki/Euclidean_distance): measures the shortest distance between two vectors.\n- [Cosine distance](https://en.wikipedia.org/wiki/Cosine_similarity#Cosine_distance): measures the cosine of the angle between two vectors.\n- [Dot product](https://mathworld.wolfram.com/DotProduct.html): calculates the cosine of the angle multiplied by the product of corresponding vector magnitudes. If you know that all the vector embeddings in your dataset are normalized, then you can use `DOT_PRODUCT()` as a distance function.\n- [K-nearest neighbors (KNN)](https://en.wikipedia.org/wiki/K-nearest_neighbors_algorithm): a supervised machine learning algorithm used to solve classification or regression problems.\n\nYou can use vector distance functions to perform K-nearest neighbors (KNN)\nvector search for use cases like similarity search or retrieval-augmented\ngeneration. Spanner supports the `COSINE_DISTANCE()`,\n`EUCLIDEAN_DISTANCE()`, and `DOT_PRODUCT()` functions, which operate on vector\nembeddings, allowing you to find the KNN of the input embedding.\n\nFor example, after you [generate and save your operational Spanner\ndata as vector embeddings](/spanner/docs/ml-tutorial-embeddings), you can then\nprovide these vector embeddings as an input parameter in your query to find the\nnearest vectors in N-dimensional space to search for semantically similar or\nrelated items.\n\nAll three distance functions take the arguments `vector1` and `vector2`, which\nare of the type `array\u003c\u003e`, and must consist of the same dimensions and have the\nsame length. For more details about these functions, see:\n\n- [`COSINE_DISTANCE()` in GoogleSQL](/spanner/docs/reference/standard-sql/mathematical_functions#cosine_distance)\n- [`EUCLIDEAN_DISTANCE()` in GoogleSQL](/spanner/docs/reference/standard-sql/mathematical_functions#euclidean_distance)\n- [`DOT_PRODUCT()` in GoogleSQL](/spanner/docs/reference/standard-sql/mathematical_functions#dot_product)\n- [Mathematical functions in PostgreSQL](/spanner/docs/reference/postgresql/functions-and-operators#mathematical) (`spanner.cosine_distance()`, `spanner.euclidean_distance()`, and `spanner.dot_product()`)\n- [Choose among vector distance functions to measure vector embeddings similarity](/spanner/docs/choose-vector-distance-function).\n\nExamples\n--------\n\nThe following examples show KNN search, KNN search over partitioned data, and\nusing a secondary index with KNN.\n\nThe examples all use `EUCLIDEAN_DISTANCE()`. You can also use\n`COSINE_DISTANCE()`. In addition, if all the vector embeddings in your dataset\nare normalized, you can use `DOT_PRODUCT()` as a distance function.\n\n### Example 1: KNN search\n\nConsider a `Documents` table that has a column (`DocEmbedding`) of precomputed\ntext embeddings from the `DocContents` bytes column. \n\n### GoogleSQL\n\n CREATE TABLE Documents (\n UserId INT64 NOT NULL,\n DocId INT64 NOT NULL,\n Author STRING(1024),\n DocContents BYTES(MAX),\n DocEmbedding ARRAY\u003cFLOAT32\u003e\n ) PRIMARY KEY (UserId, DocId);\n\n### PostgreSQL\n\n CREATE TABLE Documents (\n UserId bigint NOT NULL,\n DocId bigint NOT NULL,\n Author varchar(1024),\n DocContents bytea,\n DocEmbedding float4[],\n PRIMARY KEY (UserId, DocId)\n );\n\nAssuming that an input embedding for \"baseball, but not professional baseball\"\nis the array `[0.3, 0.3, 0.7, 0.7]`, you can find the top five nearest documents\nthat match, with the following query: \n\n### GoogleSQL\n\n SELECT DocId, DocEmbedding FROM Documents\n ORDER BY EUCLIDEAN_DISTANCE(DocEmbedding,\n ARRAY\u003cFLOAT32\u003e[0.3, 0.3, 0.7, 0.8])\n LIMIT 5;\n\n### PostgreSQL\n\n SELECT DocId, DocEmbedding FROM Documents\n ORDER BY spanner.euclidean_distance(DocEmbedding,\n '{0.3, 0.3, 0.7, 0.8}'::float4[])\n LIMIT 5;\n\nThe expected results of this example: \n\n Documents\n +---------------------------+-----------------+\n | DocId | DocEmbedding |\n +---------------------------+-----------------+\n | 24 | [8, ...] |\n +---------------------------+-----------------+\n | 25 | [6, ...] |\n +---------------------------+-----------------+\n | 26 | [3.2, ...] |\n +---------------------------+-----------------+\n | 27 | [38, ...] |\n +---------------------------+-----------------+\n | 14229 | [1.6, ...] |\n +---------------------------+-----------------+\n\n### Example 2: KNN search over partitioned data\n\nThe query in the previous example can be modified by adding conditions to the\n`WHERE` clause to limit the vector search to a subset of your data. One common\napplication of this is to search over partitioned data, such as rows that belong\nto a specific `UserId`. \n\n### GoogleSQL\n\n SELECT UserId, DocId, DocEmbedding FROM Documents\n WHERE UserId=18\n ORDER BY EUCLIDEAN_DISTANCE(DocEmbedding,\n ARRAY\u003cFLOAT32\u003e[0.3, 0.3, 0.7, 0.8])\n LIMIT 5;\n\n### PostgreSQL\n\n SELECT UserId, DocId, DocEmbedding FROM Documents\n WHERE UserId=18\n ORDER BY spanner.euclidean_distance(DocEmbedding,\n '{0.3, 0.3, 0.7, 0.8}'::float4[])\n LIMIT 5;\n\nThe expected results of this example: \n\n Documents\n +-----------+-----------------+-----------------+\n | UserId | DocId | DocEmbedding |\n +-----------+-----------------+-----------------+\n | 18 | 234 | [12, ...] |\n +-----------+-----------------+-----------------+\n | 18 | 12 | [1.6, ...] |\n +-----------+-----------------+-----------------+\n | 18 | 321 | [22, ...] |\n +-----------+-----------------+-----------------+\n | 18 | 432 | [3, ...] |\n +-----------+-----------------+-----------------+\n\n### Example 3: KNN search over secondary index ranges\n\nIf the `WHERE` clause filter you're using isn't part of the table's primary key,\nthen you can create a secondary index to accelerate the operation with an\n[index-only scan](/spanner/docs/secondary-indexes#storing-clause). \n\n### GoogleSQL\n\n CREATE INDEX DocsByAuthor\n ON Documents(Author)\n STORING (DocEmbedding);\n\n SELECT Author, DocId, DocEmbedding FROM Documents\n WHERE Author=\"Mark Twain\"\n ORDER BY EUCLIDEAN_DISTANCE(DocEmbedding,\n \u003cembeddings for \"book about the time traveling American\"\u003e)\n LIMIT 5;\n\n### PostgreSQL\n\n CREATE INDEX DocsByAuthor\n ON Documents(Author)\n INCLUDE (DocEmbedding);\n\n SELECT Author, DocId, DocEmbedding FROM Documents\n WHERE Author=\"Mark Twain\"\n ORDER BY spanner.euclidean_distance(DocEmbedding,\n \u003cembeddings for \"that book about the time traveling American\"\u003e)\n LIMIT 5;\n\nThe expected results of this example: \n\n Documents\n +------------+-----------------+-----------------+\n | Author | DocId | DocEmbedding |\n +------------+-----------------+-----------------+\n | Mark Twain | 234 | [12, ...] |\n +------------+-----------------+-----------------+\n | Mark Twain | 12 | [1.6, ...] |\n +------------+-----------------+-----------------+\n | Mark Twain | 321 | [22, ...] |\n +------------+-----------------+-----------------+\n | Mark Twain | 432 | [3, ...] |\n +------------+-----------------+-----------------+\n | Mark Twain | 375 | [9, ...] |\n +------------+-----------------+-----------------+\n\nWhat's next\n-----------\n\n- Learn more about the [GoogleSQL `COSINE_DISTANCE()`, `EUCLIDEAN_DISTANCE()`, `DOT_PRODUCT()`](/spanner/docs/reference/standard-sql/mathematical_functions) functions.\n\n- Learn more about the [PostgreSQL `spanner.cosine_distance()`, `spanner.euclidean_distance()`, `spanner.dot_product()`](/spanner/docs/reference/postgresql/functions-and-operators#mathematical) functions.\n\n- Learn more about how to [Choose among vector distance functions to measure vector embeddings similarity](/spanner/docs/choose-vector-distance-function)."]]