Znajdź najbliższy

Opis

Przeprowadza wyszukiwanie wektorowe najbliższych sąsiadów w podanym embedding polu za pomocą żądanej distance_measure.

Przykłady

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

Zachowanie

Wskaźnik odległości

Etap find_nearest(...) obsługuje te opcje odległości wektorowej:

  • euclidean: mierzy euclidean odległość między wektorami. Więcej informacji znajdziesz w artykule Euclidean.
  • cosine: porównuje wektory na podstawie kąta między nimi, co pozwala mierzyć podobieństwo, które nie jest oparte na wielkości wektorów. Zamiast odległości COSINE zalecamy używanie dot_product ze znormalizowanymi wektorami jednostkowymi, co jest matematycznie równoważne i zapewnia lepszą wydajność. Więcej informacji znajdziesz w artykule Podobieństwo cosinusowe.
  • dot_product: podobny do cosine, ale zależy od wielkości wektorów. Więcej informacji znajdziesz w artykule Iloczyn skalarny.

Wybierz miarę odległości

W zależności od tego, czy wszystkie osadzenia wektorowe są znormalizowane, możesz określić, którego pomiaru odległości użyć do znalezienia pomiaru odległości. Znormalizowany wektor dystrybucyjny ma wielkość (długość) dokładnie 1,0.

Jeśli wiesz, z jakiego pomiaru odległości korzystał Twój model podczas trenowania, użyj go do obliczenia odległości między wektorami dystrybucyjnymi.

Znormalizowane dane

Jeśli masz zbiór danych, w którym wszystkie wektory dystrybucyjne są znormalizowane, wszystkie 3 miary odległości zapewniają te same wyniki wyszukiwania semantycznego. Chociaż każda miara odległości zwraca inną wartość, wartości te są sortowane w ten sam sposób. Gdy wektory są znormalizowane, dot_product jest zwykle najbardziej wydajny obliczeniowo, ale w większości przypadków różnica jest znikoma. Jeśli jednak Twoja aplikacja jest bardzo wrażliwa na wydajność, dot_product może pomóc w dostrajaniu wydajności.

Dane nieznormalizowane

Jeśli masz zbiór danych, w którym wektory dystrybucyjne nie są znormalizowane, używanie dot_product jako miary odległości jest matematycznie nieprawidłowe, ponieważ iloczyn skalarny nie mierzy odległości. W zależności od tego, jak wygenerowano osadzenia i jaki typ wyszukiwania jest preferowany, miara odległości cosine lub euclidean daje wyniki wyszukiwania, które są subiektywnie lepsze niż wyniki uzyskane przy użyciu innych miar odległości. Aby określić, które z tych rozwiązań będzie najlepsze w Twoim przypadku, może być konieczne przeprowadzenie eksperymentu z użyciem cosine lub euclidean.

Nie wiesz, czy dane są znormalizowane czy nie

Jeśli nie masz pewności, czy Twoje dane są znormalizowane, a chcesz użyć parametru dot_product, zalecamy użycie zamiast niego parametru cosine. cosine działa podobnie jak dot_product, ale ma wbudowaną normalizację. Odległość mierzona za pomocą cosine mieści się w zakresie od 0 do 2. Wynik bliski 0 oznacza, że wektory są bardzo podobne.

Ograniczanie wyników

Możesz ograniczyć liczbę dokumentów zwracanych przez zapytanie, ustawiając pole limit.

Node.js

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

Pobieranie obliczonej odległości wektora

Obliczoną odległość wektorową możesz pobrać, przypisując nazwę właściwości wyjściowej distance_field na etapie find_nearest(...), jak pokazano w przykładzie poniżej:

Na przykład w przypadku tej kolekcji:

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

Wykonywanie wyszukiwania wektorowego z żądanym wynikiem 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();

W wyniku tego powstają te dokumenty:

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

Ograniczenia

Podczas pracy z wektorami dystrybucyjnymi pamiętaj o tym ograniczeniu:

  • Maksymalny obsługiwany wymiar osadzania to 2048. Aby przechowywać większe indeksy, użyj redukcji wymiarowości.