使用向量嵌入項目搜尋

本頁面說明如何使用 Cloud Firestore 執行 K-nearest 使用以下技術進行鄰 (KNN) 向量搜尋:

  • 儲存向量值
  • 建立及管理 KNN 向量索引
  • 使用支援的向量執行 K-nearest-Neighbor (KNN) 查詢 距離函式

儲存向量嵌入

您可以建立向量值,如文字嵌入: 存取 Cloud Firestore 資料,並將這些資料儲存在 Cloud Firestore 文件中。

使用向量嵌入功能寫入運算

以下範例說明如何將向量嵌入儲存在 Cloud Firestore 文件:

Python
from google.cloud import firestore
from google.cloud.firestore_v1.vector import Vector

firestore_client = firestore.Client()
collection = firestore_client.collection("coffee-beans")
doc = {
  "name": "Kahawa coffee beans",
  "description": "Information about the Kahawa coffee beans.",
  "embedding_field": Vector([1.0 , 2.0, 3.0])
}

collection.add(doc)
    
Node.js
import {
  Firestore,
  FieldValue,
} from "@google-cloud/firestore";

const db = new Firestore();
const coll = db.collection('coffee-beans');
await coll.add({
  name: "Kahawa coffee beans",
  description: "Information about the Kahawa coffee beans.",
  embedding_field: FieldValue.vector([1.0 , 2.0, 3.0])
});
    

使用 Cloud 函式計算向量嵌入

在每次更新文件或檔案更新時,計算及儲存向量嵌入 您可以設定 Cloud 函式

Python
@functions_framework.cloud_event
def store_embedding(cloud_event) -> None:
  """Triggers by a change to a Firestore document.
  """
  firestore_payload = firestore.DocumentEventData()
  payload = firestore_payload._pb.ParseFromString(cloud_event.data)

  collection_id, doc_id = from_payload(payload)
  # Call a function to calculate the embedding
  embedding = calculate_embedding(payload)
  # Update the document
  doc = firestore_client.collection(collection_id).document(doc_id)
  doc.set({"embedding_field": embedding}, merge=True)
    
Node.js
/**
 * A vector embedding will be computed from the
 * value of the `content` field. The vector value
 * will be stored in the `embedding` field. The
 * field names `content` and `embedding` are arbitrary
 * field names chosen for this example.
 */
async function storeEmbedding(event: FirestoreEvent<any>): Promise<void> {
  // Get the previous value of the document's `content` field.
  const previousDocumentSnapshot = event.data.before as QueryDocumentSnapshot;
  const previousContent = previousDocumentSnapshot.get("content");

  // Get the current value of the document's `content` field.
  const currentDocumentSnapshot = event.data.after as QueryDocumentSnapshot;
  const currentContent = currentDocumentSnapshot.get("content");

  // Don't update the embedding if the content field did not change
  if (previousContent === currentContent) {
    return;
  }

  // Call a function to calculate the embedding for the value
  // of the `content` field.
  const embeddingVector = calculateEmbedding(currentContent);

  // Update the `embedding` field on the document.
  await currentDocumentSnapshot.ref.update({
    embedding: embeddingVector,
  });
}
    

建立及管理向量索引

您必須先使用向量嵌入項目執行最鄰近搜尋 您必須建立相應的索引下列範例為 如何建立及管理向量索引

建立向量索引

如要建立向量索引,請使用 gcloud alpha firestore indexes composite create

gcloud
gcloud alpha firestore indexes composite create \
--collection-group=collection-group \
--query-scope=COLLECTION \
--field-config field-path=vector-field,vector-config='vector-configuration' \
--database=database-id
    

其中:

  • collection-group 是產品素材資源集合群組的 ID。
  • vector-field 是包含向量嵌入的欄位名稱。
  • database-id 是資料庫的 ID。
  • vector-configuration 包含向量 dimension 和索引類型。 dimension 是最大 2048 的整數。索引類型必須是 flat。 索引設定的格式設定如下:{"dimension":"DIMENSION", "flat": "{}"}

以下範例會建立複合式索引,包括「vector-field」欄位的向量索引 為 color 欄位遞增索引。您可以使用這種索引預先篩選 資料

gcloud
gcloud alpha firestore indexes composite create \
--collection-group=collection-group \
--query-scope=COLLECTION \
--field-config=order=ASCENDING,field-path="color" \
--field-config field-path=vector-field,vector-config='{"dimension":"1024", "flat": "{}"}' \
--database=database-id
    

列出所有向量索引

gcloud
gcloud alpha firestore indexes composite list --database=database-id

請將 database-id 替換為資料庫 ID。

刪除向量索引

gcloud
gcloud alpha firestore indexes composite delete index-id --database=database-id
    

其中:

  • index-id 是要刪除的索引 ID。 使用 indexes composite list 擷取索引 ID。
  • database-id 是資料庫的 ID。

說明向量索引

gcloud
gcloud alpha firestore indexes composite describe index-id --database=database-id
    

其中:

  • index-id 是要說明的索引 ID。使用或 indexes composite list:擷取索引 ID。
  • database-id 是資料庫的 ID。

執行最鄰近查詢

此時,您可以執行相似度搜尋,找出最接近 以及向量嵌入功能相似度搜尋需要向量索引。 如果索引不存在,Cloud Firestore 會建議要建立的索引 來部署應用程式

Python
from google.cloud.firestore_v1.base_vector_query import DistanceMeasure

collection = collection("coffee-beans")

# Requires vector index
collection.find_nearest(
   vector_field="embedding_field",
   query_vector=Vector([3.0, 1.0, 2.0]),
   distance_measure=DistanceMeasure.EUCLIDEAN,
   limit=5)
    
Node.js
import {
  Firestore,
  FieldValue,
  VectorQuery,
  VectorQuerySnapshot,
} from "@google-cloud/firestore";

// Requires single-field vector index
const vectorQuery: VectorQuery = coll.findNearest('embedding_field', FieldValue.vector([3.0, 1.0, 2.0]), {
  limit: 5,
  distanceMeasure: 'EUCLIDEAN'
});

const vectorQuerySnapshot: VectorQuerySnapshot = await vectorQuery.get();
    

向量距離

最鄰近查詢支援下列向量距離選項:

  • EUCLIDEAN:測量向量之間的 EUCLIDEAN 距離。 詳情請參閱: Euclidean
  • COSINE:根據向量之間的角度比較向量 而不是以向量規模為依據 我們建議針對單位正規化向量使用 DOT_PRODUCT,而非 COSINE 距離 (在數學上相等), 才需進行詳情請參閱: 餘弦相似度: 內容。
  • DOT_PRODUCT:與 COSINE 類似,但受到 建立向量詳情請參閱: 點號產品

預先篩選資料

如要在尋找最鄰近的項目前先預先篩選資料,可以結合 相似度搜尋與其他篩選器 (不相等篩選器除外)and和 支援 or 複合篩選器。欄位篩選器的注意事項 篩選器支援:

  • == 等於
  • in
  • array_contains
  • array_contains_any
Python
# Similarity search with pre-filter
# Requires composite vector index
collection.where("color", "==", "red").find_nearest(
   vector_field="embedding_field",
   query_vector=Vector([3.0, 1.0, 2.0]),
   distance_measure=DistanceMeasure.EUCLIDEAN,
   limit=5)
    
Node.js
// Similarity search with pre-filter
// Requires composite vector index
const preFilteredVectorQuery: VectorQuery = coll
  .where("color", "==", "red")
  .findNearest("embedding_field", FieldValue.vector([3.0, 1.0, 2.0]), {
    limit: 5,
    distanceMeasure: "EUCLIDEAN",
  });

vectorQueryResults = await preFilteredVectorQuery.get();
    

限制

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

  • 支援的嵌入維度上限為 2048。如要儲存較大的索引,請使用 降低維度
  • 最鄰近查詢傳回的文件數量上限為 1000。
  • Vector Search 不支援即時快照事件監聽器
  • 您無法使用不等式篩選器來預先篩選資料。
  • 只有 Python 和 Node.js 用戶端程式庫支援向量搜尋。

後續步驟