Buscar el más cercano

Descripción

Realiza una búsqueda vectorial de vecino más cercano en el campo embedding determinado con la distance_measure solicitada.

Sintaxis

Node.js

const results = await db.pipeline()
  .collection("cities")
  .findNearest({
      field: 'embedding',
      vectorValue: vector([1.5, 2.345]),
      distanceMeasure: 'euclidean',
  })
  .execute();

Ejemplos 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();

Comportamiento

Medición de distancia

La etapa find_nearest admite las siguientes opciones para la distancia vectorial:

  • euclidean: Mide la distancia euclidean entre los vectores. Para obtener más información, consulta Euclidean.
  • cosine: Compara vectores según el ángulo entre ellos, lo que te permite medir la similitud que no se basa en la magnitud de los vectores. Recomendamos usar dot_product con vectores normalizados de unidades en lugar de la distancia de COSINE, que es matemáticamente equivalente con un mejor rendimiento. Para obtener más información, consulta Similitud coseno.
  • dot_product: Es similar a cosine, pero se ve afectado por la magnitud de laos vectores. Para obtener más información, consulta Producto de punto.

Elige la medida de distancia

Según si todas tus embeddings de vectores están normalizadas o no, puedes determinar qué medida de distancia usar para encontrar la medida de distancia. Una embedding de vector normalizada tiene una magnitud (longitud) de exactamente 1.0.

Además, si sabes con qué medida de distancia se entrenó tu modelo, usa esa medida para calcular la distancia entre tus embeddings de vectores.

Datos normalizados

Si tienes un conjunto de datos en el que todas las embeddings de vectores están normalizadas, las tres medidas de distancia proporcionan los mismos resultados de la búsqueda semántica. En esencia, aunque cada medida de distancia muestra un valor diferente, esos valores se ordenan de la misma manera. Cuando las embeddings se normalizan, dot_product suele ser la más eficiente en términos de procesamiento, pero la diferencia es despreciable en la mayoría de los casos. Sin embargo, si tu aplicación es muy sensible al rendimiento, dot_product podría ayudarte a ajustarlo.

Datos no normalizados

Si tienes un conjunto de datos en el que las embedding de vector no están normalizadas, no es matemáticamente correcto usar dot_product como medida de distancia, porque el producto punto no mide la distancia. Según cómo se generaron las embeddings y el tipo de búsqueda que se prefiera, la medida de distancia cosine o euclidean produce resultados de búsqueda que son subjetivamente mejores que las otras medidas de distancia. Es posible que sea necesario experimentar con cosine o euclidean para determinar cuál es la mejor opción para tu caso de uso.

No sabes si los datos están normalizados o no

Si no sabes si tus datos están normalizados y quieres usar dot_product, te recomendamos que uses cosine. cosine es como dot_product con la normalización integrada. La distancia medida con cosine varía de 0 a 2. Un resultado cercano a 0 indica que los vectores son muy similares.

Limita los resultados

Puedes limitar la cantidad de documentos que devuelve la consulta configurando el 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();

Cómo recuperar la distancia vectorial calculada

Para recuperar la distancia vectorial calculada, asigna un nombre de propiedad de resultado distance_field en la etapa find_nearest, como se muestra en el siguiente ejemplo:

Por ejemplo, para la siguiente colección:

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])});

Realiza una búsqueda vectorial con un resultado solicitado 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();

Esto produce los siguientes 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}

Limitaciones

Cuando trabajes con embeddings de vector, ten en cuenta las siguiente limitación: