Descrição
Realiza uma pesquisa de vetor vizinho mais próximo no campo embedding especificado usando o distance_measure solicitado.
Sintaxe
Node.js
const results = await db.pipeline()
.collection("cities")
.findNearest({
field: 'embedding',
vectorValue: vector([1.5, 2.345]),
distanceMeasure: 'euclidean',
})
.execute();
Exemplos de clientes
Node.js
const results = await db.pipeline() .collection("cities") .findNearest({ field: "embedding", vectorValue: [1.5, 2.345], distanceMeasure: "euclidean" }) .execute();
Web
const results = await execute(db.pipeline() .collection("cities") .findNearest({ field: "embedding", vectorValue: [1.5, 2.345], distanceMeasure: "euclidean" }));
Swift
let results = try await db.pipeline() .collection("cities") .findNearest( field: Field("embedding"), vectorValue: VectorValue([1.5, 2.345]), distanceMeasure: .euclidean ) .execute()
Kotlin
val results = db.pipeline() .collection("cities") .findNearest( "embedding", FieldValue.vector(doubleArrayOf(1.5, 2.345)), FindNearestStage.DistanceMeasure.EUCLIDEAN ) .execute()
Java
Task<Pipeline.Snapshot> results = db.pipeline() .collection("cities") .findNearest( "embedding", new double[] {1.5, 2.345}, FindNearestStage.DistanceMeasure.EUCLIDEAN ) .execute();
Python
from google.cloud.firestore_v1.vector import Vector from google.cloud.firestore_v1.base_vector_query import DistanceMeasure results = ( client.pipeline() .collection("cities") .find_nearest( field="embedding", vector_value=Vector([1.5, 2.345]), distance_measure=DistanceMeasure.EUCLIDEAN, ) .execute() )
Java
Pipeline.Snapshot results = firestore .pipeline() .collection("cities") .findNearest( "embedding", new double[] {1.5, 2.345}, FindNearest.DistanceMeasure.EUCLIDEAN, new FindNearestOptions()) .execute() .get();
Comportamento
Medida de distância
A etapa find_nearest é compatível com as seguintes opções de distância vetorial:
euclidean: mede a distânciaeuclideanentre os vetores. Para saber mais, consulte Euclidiano.cosine: compara vetores com base no ângulo entre eles, o que permite medir a similaridade que não se baseia na magnitude dos vetores. Recomendamos usardot_productcom vetores normalizados unitários em vez da distância COSSENO, que é matematicamente equivalente a um melhor desempenho. Para saber mais, consulte Semelhança de cossenos.dot_product: semelhante acosine, mas é afetado pela magnitude de vetores. Para saber mais, consulte Produto escalar.
Escolha a medida de distância
Dependendo se todos os embeddings de vetor estiverem normalizadas ou não, você pode determinar qual medida de distância usar para encontrar a medida de distância. Um embedding de vetor normalizado tem uma magnitude (comprimento) de exatamente 1,0.
Além disso, se você souber com qual medida de distância o modelo foi treinado, use essa medida para calcular a distância entre os embeddings de vetor.
Dados normalizados
Se você tiver um conjunto de dados em que todos os embeddings de vetor estiverem normalizadas, as três
medidas de distância vão fornecer os mesmos resultados de pesquisa semântica. Resumindo, embora cada
medida de distância retorne um valor diferente, esses valores são classificados da mesma maneira. Quando
os embeddings estão normalizados, o dot_product geralmente é o mais eficiente
em termos computacionais, mas a diferença é insignificante na maioria dos casos. No entanto, se o
aplicativo for altamente sensível ao desempenho, dot_product poderá ajudar no
ajuste de desempenho.
Dados não normalizados
Se você tiver um conjunto de dados em que os embeddings de vetor não estiverem normalizados,
não será matematicamente correto usar dot_product como uma medida de distância,
porque o produto escalar não mede distância. Dependendo
de como os embeddings foram gerados e de qual tipo de pesquisa é a preferida,
a medida de distância cosine ou euclidean produzirá
resultados de pesquisa subjetivamente melhores do que as outras medidas de distância.
A experimentação com cosine ou euclidean pode
ser necessária para determinar qual é a melhor para seu caso de uso.
Não tem certeza se os dados estão normalizados ou não
Se você não tiver certeza se os dados estão normalizados e quiser usar
dot_product, recomendamos usar cosine.
cosine é como dot_product com a normalização integrada.
A distância medida usando cosine varia de 0 a 2. Um resultado
próximo a 0 indica que os vetores são muito semelhantes.
Limitar os resultados
É possível limitar o número de documentos retornados pela consulta definindo o campo limit.
Node.js
const results = await db.pipeline()
.collection("cities")
.findNearest({
field: 'embedding',
vectorValue: vector([1.5, 2.345]),
distanceMeasure: 'euclidean',
limit: 10,
})
.execute();
Extrair a distância vetorial calculada
É possível extrair a distância vetorial calculada atribuindo um
nome de propriedade de saída distance_field no cenário find_nearest, conforme
mostrado no exemplo a seguir:
Por exemplo, para a seguinte coleção:
Node.js
await db.collection('cities').doc('SF').set({name: 'San Francisco', embedding: vector([1.0, -1.0])});
await db.collection('cities').doc('TO').set({name: 'Toronto', embedding: vector([5.0, -10.0])});
await db.collection('cities').doc('AT').set({name: 'Atlantis', embedding: vector([2.0, -4.0])});
Fazer uma pesquisa vetorial com uma saída solicitada distance_field:
Node.js
const results = await db.pipeline()
.collection("cities")
.findNearest({
field: 'embedding',
vectorValue: vector([1.3, 2.345]),
distanceMeasure: 'euclidean',
distanceField: 'computedDistance',
})
.execute();
O que produz os seguintes documentos:
{name: 'San Francisco', embedding: vector([1.0, -1.0]), computedDistance: 3.3584259705999178},
{name: 'Atlantis', embedding: vector([2.0, -4.0]), computedDistance: 6.383496299051172},
{name: 'Toronto', embedding: vector([5.0, -10.0]), computedDistance: 12.887553103673328}
Limitações
Ao trabalhar com embeddings de vetor, observe a seguinte limitação:
- A dimensão de incorporação máxima compatível é 2048. Para armazenar índices maiores, use redução de dimensionalidade.