หน้านี้แสดงวิธีใช้ Cloud Firestore เพื่อดำเนินการ K-ใกล้ที่สุด ค้นหาเวกเตอร์เพื่อนบ้าน (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": "{}"}
ตัวอย่างต่อไปนี้สร้างดัชนีผสม รวมถึงดัชนีเวกเตอร์สำหรับฟิลด์ vector-field
และดัชนีจากน้อยไปมากสำหรับช่อง 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=vector-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
ข้อมูลที่กรองไว้ล่วงหน้า
ในการกรองข้อมูลล่วงหน้าก่อนที่จะค้นหาเพื่อนบ้านที่อยู่ใกล้ที่สุด คุณสามารถรวม
การค้นหาความคล้ายคลึงกันโดยใช้ตัวกรองอื่นๆ ยกเว้นตัวกรองอสมการ 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
- ทำความเข้าใจการอ่านและการเขียนในวงกว้าง