尋找最近的

說明

使用要求的 distance_measure,對指定 embedding 欄位執行最鄰近向量搜尋。

範例

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

行為

測量距離

find_nearest(...) 階段支援下列向量距離選項:

  • euclidean:測量向量之間的 euclidean 距離。 詳情請參閱「歐幾里得」一文。
  • cosine:根據向量之間的角度比較向量,可讓您測量不以向量大小為依據的相似度。建議您搭配使用 dot_product 與單位正規化向量,而不要使用餘弦距離,因為兩者在數學上等價,但前者效能較佳。詳情請參閱「餘弦相似度」。
  • dot_product:與 cosine 類似,但會受到向量大小影響。詳情請參閱「點積」。

選擇距離測量單位

視所有向量嵌入是否已正規化而定,您可以決定要使用哪種距離測量方式來找出距離測量結果。正規化向量嵌入的量值 (長度) 剛好為 1.0。

此外,如果您知道模型訓練時使用的距離測量方式,請使用該方式計算向量嵌入之間的距離。

正規化資料

如果資料集中的所有向量嵌入都經過正規化,則這三種距離測量方式都會提供相同的語意搜尋結果。基本上,雖然每種距離測量方式會傳回不同的值,但這些值會以相同方式排序。當嵌入內容經過正規化處理後,dot_product 通常是運算效率最高的做法,但在大多數情況下,兩者差異不大。不過,如果應用程式對效能非常敏感,dot_product 可能有助於調整效能。

未正規化的資料

如果資料集中的向量嵌入未經過正規化,則使用 dot_product 做為距離測量值在數學上並不正確,因為點積無法測量距離。視嵌入的產生方式和偏好的搜尋類型而定,cosineeuclidean 距離測量值產生的搜尋結果,在主觀上會優於其他距離測量值。您可能需要透過 cosineeuclidean 進行實驗,才能判斷哪一個最適合您的用途。

不確定資料是否經過正規化

如果您不確定資料是否已正規化,且想使用 dot_product,建議改用 cosinecosine 類似於 dot_product,但內建正規化功能。使用 cosine 測量的距離範圍為 02。結果越接近 0,表示向量越相似。

限制結果

您可以設定 limit 欄位,限制查詢傳回的文件數量。

Node.js

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

擷取計算出的向量距離

如要擷取計算出的向量距離,請在 find_nearest(...) 階段指派 distance_field 輸出屬性名稱,如下列範例所示:

舉例來說,假設有以下集合:

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

使用要求的輸出 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();

這會產生下列文件:

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

限制

使用向量嵌入時,請注意下列限制:

  • 支援的嵌入維度上限為 2048。如要儲存較大的索引,請使用降維