หน้านี้แสดงวิธีใช้ Cloud Firestore เพื่อค้นหาเวกเตอร์เพื่อนบ้าน (KNN) ที่ใกล้เคียงที่สุดโดยใช้เทคนิคต่อไปนี้
- เก็บค่าเวกเตอร์
- สร้างและจัดการดัชนีเวกเตอร์ KNN
- สร้างการค้นหา K-Nabest-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 Function
คุณสามารถตั้งค่า 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, }); }
สร้างและจัดการดัชนีเวกเตอร์
ก่อนที่จะทำการค้นหาใกล้เคียงที่สุดด้วยการฝังเวกเตอร์ คุณต้องสร้างดัชนีที่สอดคล้องกัน ตัวอย่างต่อไปนี้สาธิตวิธีสร้างและจัดการดัชนีเวกเตอร์
สร้างดัชนีเวกเตอร์ฟิลด์เดียว
หากต้องการสร้างดัชนีเวกเตอร์ช่องเดียว ให้ใช้ 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
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 ระหว่างเวกเตอร์ ดูข้อมูลเพิ่มเติมได้ที่ยุคลิดCOSINE
: เปรียบเทียบเวกเตอร์โดยอิงตามมุมระหว่างเวกเตอร์ ซึ่งจะช่วยให้คุณวัดความคล้ายคลึงกันที่ไม่ได้อิงตามขนาดของเวกเตอร์ได้ เราขอแนะนำให้ใช้DOT_PRODUCT
กับเวกเตอร์ที่ปรับให้เป็นหน่วยมาตรฐานแทนระยะห่างของ COSINE ซึ่งในทางคณิตศาสตร์แล้วจะมีประสิทธิภาพดีกว่า ดูข้อมูลเพิ่มเติมได้ที่ความคล้ายคลึงกันของโคไซน์DOT_PRODUCT
: คล้ายกับCOSINE
แต่ได้รับผลกระทบจากขนาดของเวกเตอร์ ดูข้อมูลเพิ่มเติมได้ที่ Dot product
ข้อมูลที่กรองไว้ล่วงหน้า
ในการกรองข้อมูลล่วงหน้าก่อนที่จะพบเพื่อนบ้านที่อยู่ใกล้ที่สุด คุณสามารถใช้การค้นหาที่คล้ายกันร่วมกับตัวกรองอื่นๆ ยกเว้นตัวกรองอสมการ ระบบรองรับตัวกรองแบบผสม 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 หากต้องการจัดเก็บดัชนีที่ใหญ่กว่า ให้ใช้การลดมิติข้อมูล
- จำนวนเอกสารสูงสุดที่จะแสดงจากคำค้นหาใกล้เคียงที่สุดคือ 1,000 รายการ
- การค้นหาเวกเตอร์ไม่รองรับ Listener ของสแนปชอตแบบเรียลไทม์
- คุณจะใช้ตัวกรองอสมการเพื่อกรองข้อมูลล่วงหน้าไม่ได้
- เฉพาะไลบรารีของไคลเอ็นต์ Python และ Node.js เท่านั้นที่รองรับการค้นหาเวกเตอร์
ขั้นตอนถัดไป
- อ่านเกี่ยวกับแนวทางปฏิบัติแนะนำสำหรับ Cloud Firestore
- ทำความเข้าใจการอ่านและการเขียนในวงกว้าง