最も近いものを検索

説明

リクエストされた distance_measure を使用して、指定された embedding フィールドで最近傍ベクトル検索を実行します。

構文

Node.js

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

クライアントの例

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

動作

距離測定

find_nearest ステージでは、ベクトル距離に関する次のオプションがサポートされています。

  • euclidean: ベクトル間の euclidean 距離を測定します。 詳細については、ユークリッドをご覧ください。
  • cosine: ベクター間の角度に基づいてベクターを比較します。これにより、ベクターの大きさに基づかない類似性を測定できます。コサイン距離ではなく、単位正規化ベクターを使用して dot_product を使用することをおすすめします。数学的には、パフォーマンスが向上します。詳細については、コサイン類似度をご覧ください。
  • dot_product: cosine に似ていますが、ベクターの大きさの影響を受けます。詳細については、ドット積をご覧ください。

距離測定を選択する

すべてのベクトル エンベディングが正規化されているかどうかによって、距離測定を見つけるために使用する距離測定を決定できます。正規化されたベクトル エンベディングの強度(長さ)は正確に 1.0 です。

また、モデルのトレーニングに使用された距離測定がわかっている場合は、その距離測定を使用してベクトル エンベディング間の距離を計算します。

正規化されたデータ

すべてのベクトル エンベディングが正規化されたデータセットがある場合、3 つの距離測定はすべて同じセマンティック検索の結果を提供します。基本的に、各距離測定から異なる値が返されますが、値の並べ替え方法は同じです。エンべディングが正規化されている場合、通常は dot_product が最も計算効率が優れていますが、ほとんどの場合、その差はごくわずかです。ただし、アプリケーションのパフォーマンスが非常に重要である場合は、dot_product がパフォーマンス チューニングに役立つ場合があります。

正規化されていないデータ

ベクトル エンベディングが正規化されていないデータセットがある場合、ドット積は距離を測定しないため、dot_product を距離測定として使用することは数学的に正しいものではありません。エンベディングの生成方法と優先する検索タイプに応じて、cosine または euclidean 距離測定のいずれかを使用すると、もう一方よりも主観的に優れた検索結果が得られます。cosine または euclidean を試して、ユースケースにどちらが最適かを判断しなければならない場合があります。

データが正規化されているかどうか不明

データが正規化されているかどうかが不明な場合に dot_product を使用する場合は、代わりに cosine を使用することをおすすめします。cosine は、正規化が組み込まれた 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}

制限事項

ベクター エンベディングを使用する場合は、次の制限事項に注意してください。

  • サポートされているエンべディング ディメンションの最大値は 2,048 です。サイズの大きいインデックスを保存するには、次元削減を使用します。