Tìm kiếm bằng cách nhúng vectơ

Trang này hướng dẫn bạn cách sử dụng Cloud Firestore để thực hiện tìm kiếm vectơ K lân cận gần nhất (KNN) bằng các kỹ thuật sau:

  • Lưu trữ các giá trị vectơ
  • Tạo và quản lý chỉ mục vectơ KNN
  • Đưa ra một truy vấn K-láng giềng gần nhất (KNN) bằng cách sử dụng một trong các biện pháp khoảng cách vectơ được hỗ trợ

Lưu trữ vectơ nhúng

Bạn có thể tạo các giá trị vectơ như các vectơ nhúng văn bản từ dữ liệu Cloud Firestore và lưu trữ chúng trong các tài liệu Cloud Firestore.

Thao tác ghi bằng một vectơ nhúng

Ví dụ sau đây cho thấy cách lưu trữ một vectơ nhúng trong tài liệu 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([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])
});
Tìm
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
}
Java
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();

Tính toán các vectơ nhúng bằng Cloud Function

Để tính toán và lưu trữ các vectơ nhúng bất cứ khi nào một tài liệu được cập nhật hoặc tạo, bạn có thể thiết lập một Cloud Function:

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,
  });
}
Tìm
  // Not yet supported in the Go client library
Java
  // Not yet supported in the Java client library

Tạo và quản lý chỉ mục vectơ

Trước khi có thể thực hiện tìm kiếm lân cận gần nhất bằng các vectơ nhúng, bạn phải tạo một chỉ mục tương ứng. Các ví dụ sau đây minh hoạ cách tạo và quản lý chỉ mục vectơ bằng Google Cloud CLI. Bạn cũng có thể quản lý chỉ mục vectơ bằng Firebase CLI và Terraform.

Tạo chỉ mục vectơ

Trước khi tạo chỉ mục vectơ, hãy nâng cấp lên phiên bản mới nhất của Google Cloud CLI:

gcloud components update

Để tạo chỉ mục vectơ, hãy dùng 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

trong đó:

  • collection-group là mã của nhóm bộ sưu tập.
  • vector-field là tên của trường chứa vectơ nhúng.
  • database-id là mã nhận dạng của cơ sở dữ liệu.
  • vector-configuration bao gồm vectơ dimension và loại chỉ mục. dimension là một số nguyên lên đến 2048. Loại chỉ mục phải là flat. Định dạng cấu hình chỉ mục như sau: {"dimension":"DIMENSION", "flat": "{}"}.

Ví dụ sau đây sẽ tạo một chỉ mục kết hợp, bao gồm một chỉ mục vectơ cho trường vector-field và một chỉ mục tăng dần cho trường color. Bạn có thể sử dụng loại chỉ mục này để lọc trước dữ liệu trước khi tìm kiếm lân cận.

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

Liệt kê tất cả chỉ mục vectơ

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

Thay thế database-id bằng mã nhận dạng của cơ sở dữ liệu.

Xoá chỉ mục vectơ

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

trong đó:

  • index-id là mã nhận dạng của chỉ mục cần xoá. Sử dụng indexes composite list để truy xuất mã nhận dạng chỉ mục.
  • database-id là mã nhận dạng của cơ sở dữ liệu.

Mô tả chỉ mục vectơ

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

trong đó:

  • index-id là mã nhận dạng của chỉ mục cần mô tả. Sử dụng hoặc indexes composite list để truy xuất mã nhận dạng chỉ mục.
  • database-id là mã nhận dạng của cơ sở dữ liệu.

Đưa ra truy vấn lân cận

Bạn có thể thực hiện tìm kiếm tương tự để tìm các điểm dữ liệu láng giềng gần nhất của một vectơ nhúng. Tính năng tìm kiếm tương tự yêu cầu phải có chỉ mục vectơ. Nếu không có chỉ mục, Cloud Firestore sẽ đề xuất một chỉ mục để tạo bằng gcloud CLI.

Ví dụ sau đây tìm 10 điểm dữ liệu láng giềng gần nhất của vectơ truy vấn.

Python
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();
Tìm
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
}
Java
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();

Khoảng cách vectơ

Các truy vấn tìm lân cận gần nhất hỗ trợ các lựa chọn sau cho khoảng cách vectơ:

  • EUCLIDEAN: Đo khoảng cách EUCLIDEAN giữa các vectơ. Để tìm hiểu thêm, hãy xem phần Euclidean.
  • COSINE: So sánh các vectơ dựa trên góc giữa chúng, cho phép bạn đo lường độ tương đồng không dựa trên độ lớn của vectơ. Bạn nên sử dụng DOT_PRODUCT với các vectơ được chuẩn hoá đơn vị thay vì khoảng cách COSINE. Khoảng cách này tương đương về mặt toán học với hiệu suất tốt hơn. Để tìm hiểu thêm, hãy xem bài viết Độ tương đồng cosine.
  • DOT_PRODUCT: Tương tự như COSINE nhưng chịu ảnh hưởng của độ lớn của các vectơ. Để tìm hiểu thêm, hãy xem bài viết Tích vô hướng.

Chọn đơn vị đo khoảng cách

Tuỳ thuộc vào việc tất cả các mục nhúng vectơ của bạn có được chuẩn hoá hay không, bạn có thể xác định biện pháp khoảng cách cần sử dụng để tìm biện pháp khoảng cách. Một vectơ nhúng được chuẩn hoá có độ lớn (chiều dài) chính xác là 1.0.

Ngoài ra, nếu bạn biết mô hình của mình được huấn luyện bằng phương pháp đo khoảng cách nào, hãy sử dụng phương pháp đo khoảng cách đó để tính khoảng cách giữa các vectơ nhúng.

Dữ liệu được chuẩn hoá

Nếu bạn có một tập dữ liệu mà tất cả các mục nhúng vectơ đều được chuẩn hoá, thì cả 3 phép đo khoảng cách đều cung cấp cùng một kết quả tìm kiếm ngữ nghĩa. Về cơ bản, mặc dù mỗi phép đo khoảng cách trả về một giá trị khác nhau, nhưng các giá trị đó sắp xếp theo cùng một cách. Khi các vectơ nhúng được chuẩn hoá, DOT_PRODUCT thường là phương pháp hiệu quả nhất về mặt tính toán, nhưng sự khác biệt là không đáng kể trong hầu hết các trường hợp. Tuy nhiên, nếu ứng dụng của bạn có độ nhạy cao về hiệu suất, thì DOT_PRODUCT có thể giúp điều chỉnh hiệu suất.

Dữ liệu chưa được chuẩn hoá

Nếu bạn có một tập dữ liệu mà các vectơ nhúng không được chuẩn hoá, thì việc sử dụng DOT_PRODUCT làm thước đo khoảng cách là không chính xác về mặt toán học vì tích vô hướng không đo khoảng cách. Tuỳ thuộc vào cách tạo các vectơ nhúng và loại tìm kiếm mà bạn muốn, thước đo khoảng cách COSINE hoặc EUCLIDEAN sẽ tạo ra kết quả tìm kiếm chủ quan tốt hơn so với các thước đo khoảng cách khác. Bạn có thể cần thử nghiệm với COSINE hoặc EUCLIDEAN để xác định lựa chọn nào phù hợp nhất với trường hợp sử dụng của mình.

Không chắc chắn liệu dữ liệu có được chuẩn hoá hay không

Nếu không chắc chắn liệu dữ liệu của mình có được chuẩn hoá hay không và bạn muốn sử dụng DOT_PRODUCT, thì bạn nên sử dụng COSINE. COSINE giống như DOT_PRODUCT nhưng có sẵn tính năng chuẩn hoá. Khoảng cách đo bằng COSINE nằm trong khoảng từ 0 đến 2. Kết quả gần với 0 cho biết các vectơ rất giống nhau.

Lọc trước tài liệu

Để lọc trước các tài liệu trước khi tìm thấy các hàng xóm gần nhất, bạn có thể kết hợp một tìm kiếm tương tự với các toán tử truy vấn khác. Bộ lọc kết hợp andor được hỗ trợ. Để biết thêm thông tin về các bộ lọc trường được hỗ trợ, hãy xem phần Toán tử truy vấn.

Python
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();
Tìm
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
}
Java
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();

Truy xuất khoảng cách vectơ đã tính

Bạn có thể truy xuất khoảng cách vectơ đã tính bằng cách chỉ định tên thuộc tính đầu ra distance_result_field trên truy vấn FindNearest, như minh hoạ trong ví dụ sau:

Python
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'));
});
Tìm
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
}
Java
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"));
}

Nếu muốn sử dụng một mặt nạ trường để trả về một tập hợp con của các trường tài liệu cùng với một distanceResultField, thì bạn cũng phải thêm giá trị của distanceResultField vào mặt nạ trường, như minh hoạ trong ví dụ sau:

Python
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'
    });
Tìm
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
}
Java
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"));
}

Chỉ định ngưỡng khoảng cách

Bạn có thể chỉ định một ngưỡng tương tự chỉ trả về các tài liệu trong ngưỡng đó. Hành vi của trường ngưỡng phụ thuộc vào đơn vị đo khoảng cách mà bạn chọn:

  • Khoảng cách EUCLIDEANCOSINE giới hạn ngưỡng đối với những tài liệu có khoảng cách nhỏ hơn hoặc bằng ngưỡng được chỉ định. Các chỉ số khoảng cách này sẽ giảm khi các vectơ trở nên tương tự nhau hơn.
  • DOT_PRODUCT khoảng cách giới hạn ngưỡng đối với những tài liệu có khoảng cách lớn hơn hoặc bằng ngưỡng đã chỉ định. Khoảng cách tích vô hướng tăng lên khi các vectơ trở nên giống nhau hơn.

Ví dụ sau đây cho thấy cách chỉ định một ngưỡng khoảng cách để trả về tối đa 10 tài liệu gần nhất, cách xa tối đa 4, 5 đơn vị bằng cách sử dụng chỉ số khoảng cách EUCLIDEAN:

Python
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);
});
Tìm
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
}
Java
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());
}

Các điểm hạn chế

Khi làm việc với các mục nhúng vectơ, hãy lưu ý những giới hạn sau:

  • Kích thước nhúng tối đa được hỗ trợ là 2048. Để lưu trữ các chỉ mục lớn hơn, hãy sử dụng giảm chiều.
  • Số lượng tài liệu tối đa cần trả về từ một truy vấn lân cận gần nhất là 1.000.
  • Tính năng tìm kiếm vectơ không hỗ trợ trình nghe ảnh chụp nhanh theo thời gian thực.
  • Chỉ các thư viện ứng dụng Python, Node.js, Go và Java mới hỗ trợ tính năng tìm kiếm vectơ.

Bước tiếp theo