Menelusuri dengan embedding vektor
Halaman ini menunjukkan cara menggunakan Firestore untuk melakukan penelusuran vektor K-nearest Neighbor (KNN) menggunakan teknik berikut:
- Menyimpan nilai vektor
- Membuat dan mengelola indeks vektor KNN
- Membuat kueri K-nearest-neighbor (KNN) menggunakan salah satu fungsi jarak vektor yang didukung
Menyimpan embedding vektor
Anda dapat membuat nilai vektor seperti embeds teks dari data Firestore, dan menyimpannya di dokumen Firestore.
Operasi tulis dengan embedding vektor
Contoh berikut menunjukkan cara menyimpan embedding vektor dalam dokumen Firestore:
Python
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]) });
Menghitung embedding vektor dengan Cloud Function
Untuk menghitung dan menyimpan embedding vektor setiap kali dokumen diperbarui atau dibuat, Anda dapat menyiapkan 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, }); }
Membuat dan mengelola indeks vektor
Sebelum dapat melakukan penelusuran tetangga terdekat dengan embedding vektor, Anda harus membuat indeks yang sesuai. Contoh berikut menunjukkan cara membuat dan mengelola indeks vektor.
Membuat indeks vektor kolom tunggal
Untuk membuat indeks vektor kolom tunggal, gunakan
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
dengan:
- collection-group adalah ID grup koleksi.
- vector-field adalah nama kolom yang berisi embedding vektor.
- database-id adalah ID database.
- vector-configuration mencakup vektor
dimension
dan jenis indeks.dimension
adalah bilangan bulat hingga 2048. Jenis indeks harusflat
. Format konfigurasi indeks sebagai berikut:{"dimension":"DIMENSION", "flat": "{}"}
.
Membuat indeks vektor komposit
Contoh berikut membuat indeks vektor komposit untuk kolom color
dan kolom embedding vektor.
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
Mencantumkan semua indeks vektor
gcloud
gcloud alpha firestore indexes composite list --database=database-id
Ganti database-id dengan ID database.
Menghapus indeks vektor
gcloud
gcloud alpha firestore indexes composite delete index-id --database=database-id
dengan:
- index-id adalah ID indeks yang akan dihapus.
Gunakan
indexes composite list
untuk mengambil ID indeks. - database-id adalah ID database.
Menjelaskan indeks vektor
gcloud
gcloud alpha firestore indexes composite describe index-id --database=database-id
dengan:
- index-id adalah ID indeks yang akan dijelaskan. Gunakan atau
indexes composite list
untuk mengambil ID indeks. - database-id adalah ID database.
Membuat kueri tetangga terdekat
Anda dapat melakukan penelusuran kesamaan untuk menemukan tetangga terdekat dari penyematan vektor. Penelusuran kemiripan memerlukan indeks vektor. Jika indeks tidak ada, Firestore akan menyarankan indeks untuk dibuat menggunakan gcloud CLI.
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();
Jarak vektor
Kueri tetangga terdekat mendukung opsi berikut untuk jarak vektor:
EUCLIDEAN
: Mengukur jarak EUCLIDEAN antarvektor. Untuk mempelajari lebih lanjut, lihat Euclidean.COSINE
: Membandingkan vektor berdasarkan sudut antarvektor, yang memungkinkan Anda mengukur kesamaan yang tidak berdasarkan magnitudo vektor. Sebaiknya gunakanDOT_PRODUCT
dengan vektor yang dinormalisasi unit, bukan jarak COSINE, yang secara matematis setara dengan performa yang lebih baik. Untuk mempelajari lebih lanjut, lihat Kesamaan kosinus dan mempelajari lebih lanjut.DOT_PRODUCT
: Serupa denganCOSINE
tetapi dipengaruhi oleh besarnya vektor. Untuk mempelajari lebih lanjut, lihat Produk Dot.
Filter data terlebih dahulu
Untuk memfilter data terlebih dahulu sebelum menemukan tetangga terdekat, Anda dapat menggabungkan penelusuran kemiripan dengan filter lain, kecuali filter ketidaksetaraan. Filter gabungan and
dan
or
didukung. Untuk filter kolom, filter berikut
didukung:
==
sama denganin
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();
Batasan
Saat Anda bekerja dengan embedding vektor, perhatikan batasan berikut ini:
- Dimensi penyematan maksimum yang didukung adalah 2048. Untuk menyimpan indeks yang lebih besar, gunakan pengurangan dimensi.
- Jumlah maksimum dokumen untuk ditampilkan dari kueri tetangga terdekat adalah 1.000.
- Penelusuran vektor tidak mendukung pemroses snapshot real-time.
- Anda tidak dapat menggunakan filter ketidaksetaraan untuk memfilter data terlebih dahulu.
- Hanya library klien Python dan Node.js yang mendukung penelusuran vektor.
Langkah selanjutnya
- Baca praktik terbaik untuk Firestore.
- Memahami operasi baca dan tulis dalam skala besar