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

این صفحه به شما نشان می‌دهد که چگونه از 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

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([0.18332680, 0.24160706, 0.3416704]),
}

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])
});
برو
import (
	"context"
	"fmt"
	"io"

	"cloud.google.com/go/firestore"
)

type CoffeeBean struct {
	Name           string             `firestore:"name,omitempty"`
	Description    string             `firestore:"description,omitempty"`
	EmbeddingField firestore.Vector32 `firestore:"embedding_field,omitempty"`
	Color          string             `firestore:"color,omitempty"`
}

func storeVectors(w io.Writer, projectID string) error {
	ctx := context.Background()

	// Create client
	client, err := firestore.NewClient(ctx, projectID)
	if err != nil {
		return fmt.Errorf("firestore.NewClient: %w", err)
	}
	defer client.Close()

	// Vector can be represented by Vector32 or Vector64
	doc := CoffeeBean{
		Name:           "Kahawa coffee beans",
		Description:    "Information about the Kahawa coffee beans.",
		EmbeddingField: []float32{1.0, 2.0, 3.0},
		Color:          "red",
	}
	ref := client.Collection("coffee-beans").NewDoc()
	if _, err = ref.Set(ctx, doc); err != nil {
		fmt.Fprintf(w, "failed to upsert: %v", err)
		return err
	}

	return nil
}
جاوا
import com.google.cloud.firestore.CollectionReference;
import com.google.cloud.firestore.DocumentReference;
import com.google.cloud.firestore.FieldValue;
import com.google.cloud.firestore.VectorQuery;

CollectionReference coll = firestore.collection("coffee-beans");

Map<String, Object> docData = new HashMap<>();
docData.put("name", "Kahawa coffee beans");
docData.put("description", "Information about the Kahawa coffee beans.");
docData.put("embedding_field", FieldValue.vector(new double[] {1.0, 2.0, 3.0}));

ApiFuture<DocumentReference> future = coll.add(docData);
DocumentReference documentReference = future.get();

جاسازی های برداری را با یک تابع ابری محاسبه کنید

برای محاسبه و ذخیره جاسازی های برداری هر زمان که یک سند به روز یا ایجاد می شود، می توانید یک 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,
  });
}
برو
  // Not yet supported in the Go client library
جاوا
  // Not yet supported in the Java client library

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

قبل از اینکه بتوانید نزدیکترین همسایه را با جاسازی های برداری خود انجام دهید، باید یک نمایه مربوطه ایجاد کنید. مثال‌های زیر نحوه ایجاد و مدیریت نمایه‌های برداری با Google Cloud CLI را نشان می‌دهند. نمایه های برداری را می توان با Firebase CLI و Terraform نیز مدیریت کرد .

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

قبل از ایجاد یک نمایه برداری، به آخرین نسخه Google Cloud CLI ارتقا دهید:

gcloud components update

برای ایجاد یک نمایه برداری، از gcloud firestore indexes composite create استفاده کنید:

gcloud
gcloud 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": "{}"} .

مثال زیر یک شاخص ترکیبی، شامل یک شاخص برداری برای vector-field و یک شاخص صعودی برای color فیلد ایجاد می کند. می توانید از این نوع شاخص برای پیش فیلتر کردن داده ها قبل از جستجوی نزدیکترین همسایه استفاده کنید.

gcloud
gcloud 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 firestore indexes composite list --database=database-id

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

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

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

کجا:

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

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

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

کجا:

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

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

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

مثال زیر 10 نزدیکترین همسایه بردار پرس و جو را پیدا می کند.

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

collection = db.collection("coffee-beans")

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

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

const vectorQuerySnapshot: VectorQuerySnapshot = await vectorQuery.get();
برو
import (
	"context"
	"fmt"
	"io"

	"cloud.google.com/go/firestore"
)

func vectorSearchBasic(w io.Writer, projectID string) error {
	ctx := context.Background()

	// Create client
	client, err := firestore.NewClient(ctx, projectID)
	if err != nil {
		return fmt.Errorf("firestore.NewClient: %w", err)
	}
	defer client.Close()

	collection := client.Collection("coffee-beans")

	// Requires a vector index
	// https://firebase.google.com/docs/firestore/vector-search#create_and_manage_vector_indexes
	vectorQuery := collection.FindNearest("embedding_field",
		[]float32{3.0, 1.0, 2.0},
		5,
		// More info: https://firebase.google.com/docs/firestore/vector-search#vector_distances
		firestore.DistanceMeasureEuclidean,
		nil)

	docs, err := vectorQuery.Documents(ctx).GetAll()
	if err != nil {
		fmt.Fprintf(w, "failed to get vector query results: %v", err)
		return err
	}

	for _, doc := range docs {
		fmt.Fprintln(w, doc.Data()["name"])
	}
	return nil
}
جاوا
import com.google.cloud.firestore.VectorQuery;
import com.google.cloud.firestore.VectorQuerySnapshot;

VectorQuery vectorQuery = coll.findNearest(
        "embedding_field",
        new double[] {3.0, 1.0, 2.0},
        /* limit */ 10,
        VectorQuery.DistanceMeasure.EUCLIDEAN);

ApiFuture<VectorQuerySnapshot> future = vectorQuery.get();
VectorQuerySnapshot vectorQuerySnapshot = future.get();

فواصل برداری

پرس و جوهای نزدیکترین همسایه از گزینه های زیر برای فاصله برداری پشتیبانی می کنند:

  • EUCLIDEAN : فاصله EUCLIDEAN بین بردارها را اندازه گیری می کند. برای کسب اطلاعات بیشتر، اقلیدسی را ببینید.
  • COSINE : بردارها را بر اساس زاویه بین آنها مقایسه می کند که به شما امکان می دهد شباهتی را اندازه گیری کنید که بر اساس بزرگی بردارها نیست. توصیه می کنیم از DOT_PRODUCT با بردارهای نرمال شده واحد به جای فاصله COSINE استفاده کنید که از نظر ریاضی با عملکرد بهتر معادل است. برای کسب اطلاعات بیشتر به شباهت کسینوس مراجعه کنید تا بیشتر بدانید.
  • DOT_PRODUCT : شبیه COSINE است اما تحت تأثیر بزرگی بردارها است. برای کسب اطلاعات بیشتر، محصول Dot را ببینید.

اندازه گیری فاصله را انتخاب کنید

بسته به اینکه آیا همه جاسازی‌های برداری شما عادی هستند یا نه، می‌توانید تعیین کنید که از کدام اندازه‌گیری فاصله برای یافتن اندازه‌گیری فاصله استفاده کنید. یک تعبیه برداری نرمال شده دارای بزرگی (طول) دقیقاً 1.0 است.

علاوه بر این، اگر می دانید مدل شما با کدام اندازه گیری فاصله آموزش داده شده است، از آن اندازه گیری فاصله برای محاسبه فاصله بین جاسازی های برداری خود استفاده کنید.

داده های عادی

اگر مجموعه داده ای دارید که در آن همه جاسازی های برداری عادی شده است، هر سه اندازه گیری فاصله نتایج جستجوی معنایی یکسانی را ارائه می دهند. در اصل، اگرچه هر اندازه‌گیری فاصله مقدار متفاوتی را برمی‌گرداند، اما این مقادیر به همان روش مرتب می‌شوند. وقتی تعبیه‌ها عادی می‌شوند، DOT_PRODUCT معمولاً از نظر محاسباتی کارآمدترین است، اما تفاوت در بیشتر موارد ناچیز است. با این حال، اگر برنامه شما به عملکرد بسیار حساس است، DOT_PRODUCT ممکن است به تنظیم عملکرد کمک کند.

داده های غیر عادی

اگر مجموعه داده ای دارید که در آن جاسازی های برداری عادی نشده است، از نظر ریاضی استفاده DOT_PRODUCT به عنوان اندازه گیری فاصله درست نیست، زیرا محصول نقطه ای فاصله را اندازه نمی گیرد. بسته به نحوه ایجاد جاسازی‌ها و نوع جستجو ترجیح داده می‌شود، اندازه‌گیری فاصله COSINE یا EUCLIDEAN نتایج جستجویی را تولید می‌کند که به طور ذهنی بهتر از سایر اندازه‌گیری‌های فاصله است. آزمایش با COSINE یا EUCLIDEAN ممکن است برای تعیین اینکه کدام یک برای مورد استفاده شما بهترین است، ضروری باشد.

مطمئن نیستید که داده ها نرمال یا غیر عادی هستند

اگر مطمئن نیستید که داده‌هایتان عادی هستند یا نه و می‌خواهید از DOT_PRODUCT استفاده کنید، توصیه می‌کنیم به جای آن از COSINE استفاده کنید. COSINE مانند DOT_PRODUCT با نرمال سازی داخلی است. فاصله اندازه گیری شده با استفاده از COSINE از 0 تا 2 متغیر است. نتیجه نزدیک به 0 نشان می دهد که بردارها بسیار شبیه هستند.

اسناد از پیش فیلتر

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

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

collection = db.collection("coffee-beans")

# Similarity search with pre-filter
# Requires a composite vector index
vector_query = collection.where("color", "==", "red").find_nearest(
    vector_field="embedding_field",
    query_vector=Vector([0.3416704, 0.18332680, 0.24160706]),
    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({
      vectorField: "embedding_field",
      queryVector: [3.0, 1.0, 2.0],
      limit: 5,
      distanceMeasure: "EUCLIDEAN",
    });

const vectorQueryResults = await preFilteredVectorQuery.get();
برو
import (
	"context"
	"fmt"
	"io"

	"cloud.google.com/go/firestore"
)

func vectorSearchPrefilter(w io.Writer, projectID string) error {
	ctx := context.Background()

	// Create client
	client, err := firestore.NewClient(ctx, projectID)
	if err != nil {
		return fmt.Errorf("firestore.NewClient: %w", err)
	}
	defer client.Close()

	collection := client.Collection("coffee-beans")

	// Similarity search with pre-filter
	// Requires a composite vector index
	vectorQuery := collection.Where("color", "==", "red").
		FindNearest("embedding_field",
			[]float32{3.0, 1.0, 2.0},
			5,
			// More info: https://firebase.google.com/docs/firestore/vector-search#vector_distances
			firestore.DistanceMeasureEuclidean,
			nil)

	docs, err := vectorQuery.Documents(ctx).GetAll()
	if err != nil {
		fmt.Fprintf(w, "failed to get vector query results: %v", err)
		return err
	}

	for _, doc := range docs {
		fmt.Fprintln(w, doc.Data()["name"])
	}
	return nil
}
جاوا
import com.google.cloud.firestore.VectorQuery;
import com.google.cloud.firestore.VectorQuerySnapshot;

VectorQuery preFilteredVectorQuery = coll
        .whereEqualTo("color", "red")
        .findNearest(
                "embedding_field",
                new double[] {3.0, 1.0, 2.0},
                /* limit */ 10,
                VectorQuery.DistanceMeasure.EUCLIDEAN);

ApiFuture<VectorQuerySnapshot> future = preFilteredVectorQuery.get();
VectorQuerySnapshot vectorQuerySnapshot = future.get();

فاصله برداری محاسبه شده را بازیابی کنید

همانطور که در مثال زیر نشان داده شده است، می توانید فاصله برداری محاسبه شده را با اختصاص نام ویژگی خروجی distance_result_field در پرس و جو FindNearest بازیابی کنید:

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

collection = db.collection("coffee-beans")

vector_query = collection.find_nearest(
    vector_field="embedding_field",
    query_vector=Vector([0.3416704, 0.18332680, 0.24160706]),
    distance_measure=DistanceMeasure.EUCLIDEAN,
    limit=10,
    distance_result_field="vector_distance",
)

docs = vector_query.stream()

for doc in docs:
    print(f"{doc.id}, Distance: {doc.get('vector_distance')}")
Node.js
const vectorQuery: VectorQuery = coll.findNearest(
    {
      vectorField: 'embedding_field',
      queryVector: [3.0, 1.0, 2.0],
      limit: 10,
      distanceMeasure: 'EUCLIDEAN',
      distanceResultField: 'vector_distance'
    });

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

snapshot.forEach((doc) => {
  console.log(doc.id, ' Distance: ', doc.get('vector_distance'));
});
برو
import (
	"context"
	"fmt"
	"io"

	"cloud.google.com/go/firestore"
)

func vectorSearchDistanceResultField(w io.Writer, projectID string) error {
	ctx := context.Background()

	client, err := firestore.NewClient(ctx, projectID)
	if err != nil {
		return fmt.Errorf("firestore.NewClient: %w", err)
	}
	defer client.Close()

	collection := client.Collection("coffee-beans")

	// Requires a vector index
	// https://firebase.google.com/docs/firestore/vector-search#create_and_manage_vector_indexes
	vectorQuery := collection.FindNearest("embedding_field",
		[]float32{3.0, 1.0, 2.0},
		10,
		firestore.DistanceMeasureEuclidean,
		&firestore.FindNearestOptions{
			DistanceResultField: "vector_distance",
		})

	docs, err := vectorQuery.Documents(ctx).GetAll()
	if err != nil {
		fmt.Fprintf(w, "failed to get vector query results: %v", err)
		return err
	}

	for _, doc := range docs {
		fmt.Fprintf(w, "%v, Distance: %v\n", doc.Data()["name"], doc.Data()["vector_distance"])
	}
	return nil
}
جاوا
import com.google.cloud.firestore.VectorQuery;
import com.google.cloud.firestore.VectorQueryOptions;
import com.google.cloud.firestore.VectorQuerySnapshot;

VectorQuery vectorQuery = coll.findNearest(
        "embedding_field",
        new double[] {3.0, 1.0, 2.0},
        /* limit */ 10,
        VectorQuery.DistanceMeasure.EUCLIDEAN,
        VectorQueryOptions.newBuilder().setDistanceResultField("vector_distance").build());

ApiFuture<VectorQuerySnapshot> future = vectorQuery.get();
VectorQuerySnapshot vectorQuerySnapshot = future.get();

for (DocumentSnapshot document : vectorQuerySnapshot.getDocuments()) {
    System.out.println(document.getId() + " Distance: " + document.get("vector_distance"));
}

اگر می‌خواهید از یک فیلد ماسک برای برگرداندن زیرمجموعه‌ای از فیلدهای سند به همراه distanceResultField استفاده کنید، باید مقدار distanceResultField را نیز در ماسک فیلد وارد کنید، همانطور که در مثال زیر نشان داده شده است:

پایتون
vector_query = collection.select(["color", "vector_distance"]).find_nearest(
    vector_field="embedding_field",
    query_vector=Vector([0.3416704, 0.18332680, 0.24160706]),
    distance_measure=DistanceMeasure.EUCLIDEAN,
    limit=10,
    distance_result_field="vector_distance",
)
Node.js
const vectorQuery: VectorQuery = coll
    .select('name', 'description', 'vector_distance')
    .findNearest({
      vectorField: 'embedding_field',
      queryVector: [3.0, 1.0, 2.0],
      limit: 10,
      distanceMeasure: 'EUCLIDEAN',
      distanceResultField: 'vector_distance'
    });
برو
import (
	"context"
	"fmt"
	"io"

	"cloud.google.com/go/firestore"
)

func vectorSearchDistanceResultFieldMasked(w io.Writer, projectID string) error {
	ctx := context.Background()

	client, err := firestore.NewClient(ctx, projectID)
	if err != nil {
		return fmt.Errorf("firestore.NewClient: %w", err)
	}
	defer client.Close()

	collection := client.Collection("coffee-beans")

	// Requires a vector index
	// https://firebase.google.com/docs/firestore/vector-search#create_and_manage_vector_indexes
	vectorQuery := collection.Select("color", "vector_distance").
		FindNearest("embedding_field",
			[]float32{3.0, 1.0, 2.0},
			10,
			firestore.DistanceMeasureEuclidean,
			&firestore.FindNearestOptions{
				DistanceResultField: "vector_distance",
			})

	docs, err := vectorQuery.Documents(ctx).GetAll()
	if err != nil {
		fmt.Fprintf(w, "failed to get vector query results: %v", err)
		return err
	}

	for _, doc := range docs {
		fmt.Fprintf(w, "%v, Distance: %v\n", doc.Data()["color"], doc.Data()["vector_distance"])
	}
	return nil
}
جاوا
import com.google.cloud.firestore.VectorQuery;
import com.google.cloud.firestore.VectorQueryOptions;
import com.google.cloud.firestore.VectorQuerySnapshot;

VectorQuery vectorQuery = coll
        .select("name", "description", "vector_distance")
        .findNearest(
          "embedding_field",
          new double[] {3.0, 1.0, 2.0},
          /* limit */ 10,
          VectorQuery.DistanceMeasure.EUCLIDEAN,
          VectorQueryOptions.newBuilder()
            .setDistanceResultField("vector_distance")
            .build());

ApiFuture<VectorQuerySnapshot> future = vectorQuery.get();
VectorQuerySnapshot vectorQuerySnapshot = future.get();

for (DocumentSnapshot document : vectorQuerySnapshot.getDocuments()) {
    System.out.println(document.getId() + " Distance: " + document.get("vector_distance"));
}

یک آستانه فاصله را مشخص کنید

شما می توانید یک آستانه تشابه را تعیین کنید که فقط اسناد داخل آستانه را برمی گرداند. رفتار فیلد آستانه به اندازه گیری فاصله ای که انتخاب می کنید بستگی دارد:

  • فاصله EUCLIDEAN و COSINE آستانه را محدود به اسنادی می کند که فاصله آنها کمتر یا مساوی آستانه مشخص شده باشد. این اندازه گیری های فاصله با شبیه شدن بردارها کاهش می یابد.
  • فاصله DOT_PRODUCT آستانه را به اسنادی محدود می کند که فاصله آنها بیشتر یا مساوی آستانه تعیین شده است. فاصله محصول نقطه ای با شبیه شدن بردارها افزایش می یابد.

مثال زیر نشان می‌دهد که چگونه با استفاده از متریک فاصله EUCLIDEAN یک آستانه فاصله را برای بازگرداندن حداکثر 10 سند که حداکثر 4.5 واحد دورتر هستند، تعیین کنید:

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

collection = db.collection("coffee-beans")

vector_query = collection.find_nearest(
    vector_field="embedding_field",
    query_vector=Vector([0.3416704, 0.18332680, 0.24160706]),
    distance_measure=DistanceMeasure.EUCLIDEAN,
    limit=10,
    distance_threshold=4.5,
)

docs = vector_query.stream()

for doc in docs:
    print(f"{doc.id}")
Node.js
const vectorQuery: VectorQuery = coll.findNearest({
  vectorField: 'embedding_field',
  queryVector: [3.0, 1.0, 2.0],
  limit: 10,
  distanceMeasure: 'EUCLIDEAN',
  distanceThreshold: 4.5
});

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

snapshot.forEach((doc) => {
  console.log(doc.id);
});
برو
import (
	"context"
	"fmt"
	"io"

	"cloud.google.com/go/firestore"
)

func vectorSearchDistanceThreshold(w io.Writer, projectID string) error {
	ctx := context.Background()

	client, err := firestore.NewClient(ctx, projectID)
	if err != nil {
		return fmt.Errorf("firestore.NewClient: %w", err)
	}
	defer client.Close()

	collection := client.Collection("coffee-beans")

	// Requires a vector index
	// https://firebase.google.com/docs/firestore/vector-search#create_and_manage_vector_indexes
	vectorQuery := collection.FindNearest("embedding_field",
		[]float32{3.0, 1.0, 2.0},
		10,
		firestore.DistanceMeasureEuclidean,
		&firestore.FindNearestOptions{
			DistanceThreshold: firestore.Ptr[float64](4.5),
		})

	docs, err := vectorQuery.Documents(ctx).GetAll()
	if err != nil {
		fmt.Fprintf(w, "failed to get vector query results: %v", err)
		return err
	}

	for _, doc := range docs {
		fmt.Fprintln(w, doc.Data()["name"])
	}
	return nil
}
جاوا
import com.google.cloud.firestore.VectorQuery;
import com.google.cloud.firestore.VectorQueryOptions;
import com.google.cloud.firestore.VectorQuerySnapshot;

VectorQuery vectorQuery = coll.findNearest(
        "embedding_field",
        new double[] {3.0, 1.0, 2.0},
        /* limit */ 10,
        VectorQuery.DistanceMeasure.EUCLIDEAN,
        VectorQueryOptions.newBuilder()
          .setDistanceThreshold(4.5)
          .build());

ApiFuture<VectorQuerySnapshot> future = vectorQuery.get();
VectorQuerySnapshot vectorQuerySnapshot = future.get();

for (DocumentSnapshot document : vectorQuerySnapshot.getDocuments()) {
    System.out.println(document.getId());
}

محدودیت ها

همانطور که با جاسازی های برداری کار می کنید، به محدودیت های زیر توجه کنید:

  • حداکثر بعد تعبیه پشتیبانی شده 2048 است. برای ذخیره نمایه های بزرگتر، از کاهش ابعاد استفاده کنید.
  • حداکثر تعداد اسنادی که باید از یک جستار نزدیکترین همسایه بازگردانده شود 1000 است.
  • جستجوی برداری از شنوندگان لحظه‌ای فوری پشتیبانی نمی‌کند.
  • فقط کتابخانه های کلاینت Python، Node.js، Go و Java از جستجوی برداری پشتیبانی می کنند.

بعدش چی