Nächstgelegene finden

Beschreibung

Führt eine Vektorsuche nach dem nächsten Nachbarn im angegebenen Feld embedding mit dem angeforderten distance_measure aus.

Beispiele

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",
        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();
Go
snapshot := client.Pipeline().Collection("cities").
	FindNearest("embedding", []float64{1.5, 2.345}, firestore.PipelineDistanceMeasureEuclidean).
	Execute(ctx)

Verhalten

Distanzmesswert

Die Phase find_nearest(...) unterstützt die folgenden Optionen für die Vektorentfernung:

  • euclidean: Misst die euclidean-Entfernung zwischen den Vektoren. Weitere Informationen finden Sie unter Euklidische Entfernung.
  • cosine: Vergleicht Vektoren anhand des Winkels zwischen ihnen. So können Sie die Ähnlichkeit messen, die nicht auf der Größe der Vektoren basiert. Wir empfehlen, dot_product mit einheitsnormalisierten Vektoren anstelle der COSINE-Entfernung zu verwenden, da dies mathematisch gleichwertig ist und eine bessere Leistung bietet. Weitere Informationen finden Sie unter Kosinusähnlichkeit.
  • dot_product: Ähnlich wie cosine, wird aber von der Größe der Vektoren beeinflusst. Weitere Informationen finden Sie unter Skalarprodukt.

Distanzmesswert auswählen

Je nachdem, ob alle Ihre Vektoreinbettungen normalisiert sind oder nicht, können Sie bestimmen, welcher Distanzmesswert verwendet werden soll. Eine normalisierte Vektoreinbettung hat eine Größe (Länge) von genau 1,0.

Wenn Sie außerdem wissen, mit welchem Distanzmesswert Ihr Modell trainiert wurde, verwenden Sie diesen Distanzmesswert, um die Entfernung zwischen Ihren Vektoreinbettungen zu berechnen.

Normalisierte Daten

Wenn Sie ein Dataset haben, in dem alle Vektoreinbettungen normalisiert sind, liefern alle drei Distanzmesswerte dieselben semantischen Suchergebnisse. Obwohl jeder Distanzmesswert einen anderen Wert zurückgibt, werden diese Werte auf dieselbe Weise sortiert. Wenn Einbettungen normalisiert sind, ist dot_product in der Regel die recheneffizienteste Methode, aber der Unterschied ist in den meisten Fällen vernachlässigbar. Wenn Ihre Anwendung jedoch sehr leistungsabhängig ist, kann dot_product bei der Leistungsoptimierung helfen.

Nicht normalisierte Daten

Wenn Sie ein Dataset haben, in dem Vektoreinbettungen nicht normalisiert sind, ist es mathematisch nicht korrekt, dot_product als Distanzmesswert zu verwenden, da das Skalarprodukt keine Entfernung misst. Je nachdem, wie die Einbettungen generiert wurden und welche Art von Suche bevorzugt wird, liefert entweder der Distanzmesswert cosine oder euclidean Suchergebnisse, die subjektiv besser sind als die anderen Distanzmesswerte. Möglicherweise müssen Sie mit cosine oder euclidean experimentieren, um zu ermitteln, welcher für Ihren Anwendungsfall am besten geeignet ist.

Sie sind sich nicht sicher, ob die Daten normalisiert oder nicht normalisiert sind

Wenn Sie sich nicht sicher sind, ob Ihre Daten normalisiert sind, und Sie dot_product verwenden möchten, empfehlen wir Ihnen, stattdessen cosine zu verwenden. cosine ist wie dot_product, nur mit integrierter Normalisierung. Die mit cosine gemessene Entfernung liegt zwischen 0 und 2. Ein Ergebnis, das nahe bei 0 liegt, bedeutet, dass die Vektoren sehr ähnlich sind.

Ergebnisse begrenzen

Sie können die Anzahl der von der Abfrage zurückgegebenen Dokumente begrenzen, indem Sie das limit Feld festlegen.

Node.js

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

Berechnete Vektorentfernung abrufen

Sie können die berechnete Vektorentfernung abrufen, indem Sie in der distance_field Phasefind_nearest(...) einen Namen für die Ausgabeeigenschaft zuweisen, wie im folgenden Beispiel gezeigt:

Beispiel für die folgende Sammlung:

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

Führen Sie eine Vektorsuche mit einem angeforderten Ausgabe distance_field aus:

Node.js

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

Dadurch werden die folgenden Dokumente erstellt:

{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}

Beschränkungen

Beachten Sie bei der Arbeit mit Vektoreinbettungen die folgende Beschränkung:

  • Die maximal unterstützte Einbettungsdimension ist 2048. Verwenden Sie die Dimensionsreduktion, um größere Indexe zu speichern.