جستجو با جاسازی های برداری

این صفحه به شما نشان می‌دهد که چگونه از Cloud Firestore برای انجام جستجوهای برداری K-نزدیک‌ترین همسایه (KNN) با استفاده از این تکنیک‌ها استفاده کنید:

  • ذخیره مقادیر برداری
  • نمایه های برداری KNN را ایجاد و مدیریت کنید
  • با استفاده از یکی از توابع فاصله برداری پشتیبانی شده، یک جستار K-nearest-neighbor (KNN) ایجاد کنید.

جاسازی های وکتور فروشگاهی

می توانید مقادیر برداری مانند جاسازی متن را از داده های Cloud Firestore خود ایجاد کنید و آنها را در اسناد Cloud Firestore ذخیره کنید.

عملیات را با جاسازی برداری بنویسید

مثال زیر نحوه ذخیره وکتور تعبیه شده در یک سند Cloud Firestore را نشان می دهد:

پایتون
from google.cloud import firestore
from google.cloud.firestore_v1.vector import Vector

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 Function را تنظیم کنید:

پایتون
@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 شناسه گروه مجموعه است.
  • vector-field نام فیلدی است که حاوی جاسازی برداری است.
  • database-id شناسه پایگاه داده است.
  • vector-configuration شامل dimension برداری و نوع شاخص است. dimension یک عدد صحیح تا 2048 است. نوع شاخص باید flat باشد. پیکربندی فهرست را به صورت زیر قالب بندی کنید: {"dimension":" DIMENSION ", "flat": "{}"} .

یک نمایه برداری ترکیبی ایجاد کنید

مثال زیر یک شاخص برداری ترکیبی برای 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=field,vector-config='{"dimension":"1024", "flat": "{}"}' \
--database=database-id
    

فهرست تمام نمایه های برداری

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

شناسه پایگاه داده را جایگزین database-id کنید.

یک شاخص برداری را حذف کنید

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

جایی که:

  • index-id شناسه ایندکس برای حذف است. indexes composite list برای بازیابی شناسه فهرست استفاده کنید.
  • database-id شناسه پایگاه داده است.

یک شاخص برداری را توصیف کنید

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

جایی که:

  • index-id شناسه ایندکس برای توصیف است. برای بازیابی شناسه فهرست indexes composite list استفاده کنید.
  • database-id شناسه پایگاه داده است.

پرس و جوی نزدیکترین همسایه را انجام دهید

برای یافتن نزدیکترین همسایگان یک جاسازی برداری، می توانید یک جستجوی مشابه انجام دهید. جستجوهای مشابه به نمایه های برداری نیاز دارند. اگر شاخصی وجود نداشته باشد، Cloud Firestore نمایه ای را برای ایجاد با استفاده از gCloud CLI پیشنهاد می کند.

پایتون
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 بین بردارها را اندازه گیری می کند. برای کسب اطلاعات بیشتر، اقلیدسی را ببینید.
  • COSINE : بردارها را بر اساس زاویه بین آنها مقایسه می کند که به شما امکان می دهد شباهتی را اندازه گیری کنید که بر اساس بزرگی بردارها نیست. توصیه می کنیم از DOT_PRODUCT با بردارهای نرمال شده واحد به جای فاصله COSINE استفاده کنید که از نظر ریاضی با عملکرد بهتر معادل است. برای کسب اطلاعات بیشتر به شباهت کسینوس مراجعه کنید تا بیشتر بدانید.
  • DOT_PRODUCT : شبیه COSINE است اما تحت تأثیر بزرگی بردارها است. برای کسب اطلاعات بیشتر، محصول Dot را ببینید.

داده های پیش فیلتر

برای پیش‌فیلتر کردن داده‌ها قبل از یافتن نزدیک‌ترین همسایگان، می‌توانید جستجوی شباهت را با فیلترهای دیگر به جز فیلترهای نابرابری ترکیب کنید. فیلترهای and و or ترکیبی پشتیبانی می شوند. برای فیلترهای فیلد، فیلترهای زیر پشتیبانی می شوند:

  • == برابر با
  • in
  • array_contains
  • array_contains_any
پایتون
// 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 است.
  • جستجوی برداری از شنوندگان لحظه‌ای فوری پشتیبانی نمی‌کند.
  • شما نمی توانید از فیلترهای نابرابری برای پیش فیلتر کردن داده ها استفاده کنید.
  • فقط کتابخانه های کلاینت Python و Node.js از جستجوی برداری پشتیبانی می کنند.

بعدش چی