תיאור
מבצע חיפוש וקטורי של השכן הקרוב ביותר בשדה embedding שצוין באמצעות distance_measure המבוקש.
דוגמאות
Node.js
const results = await db.pipeline() .collection("cities") .findNearest({ field: "embedding", vectorValue: [1.5, 2.345], distanceMeasure: "euclidean" }) .execute();
Web
const results = await execute(db.pipeline() .collection("cities") .findNearest({ field: "embedding", vectorValue: [1.5, 2.345], distanceMeasure: "euclidean" }));
Swift
let results = try await db.pipeline() .collection("cities") .findNearest( field: Field("embedding"), vectorValue: VectorValue([1.5, 2.345]), distanceMeasure: .euclidean ) .execute()
Kotlin
val results = db.pipeline() .collection("cities") .findNearest( "embedding", doubleArrayOf(1.5, 2.345), FindNearestStage.DistanceMeasure.EUCLIDEAN ) .execute()
Java
Task<Pipeline.Snapshot> results = db.pipeline() .collection("cities") .findNearest( "embedding", new double[] {1.5, 2.345}, FindNearestStage.DistanceMeasure.EUCLIDEAN ) .execute();
Python
from google.cloud.firestore_v1.vector import Vector from google.cloud.firestore_v1.base_vector_query import DistanceMeasure results = ( client.pipeline() .collection("cities") .find_nearest( field="embedding", vector_value=Vector([1.5, 2.345]), distance_measure=DistanceMeasure.EUCLIDEAN, ) .execute() )
Java
Pipeline.Snapshot results = firestore .pipeline() .collection("cities") .findNearest( "embedding", new double[] {1.5, 2.345}, FindNearest.DistanceMeasure.EUCLIDEAN, new FindNearestOptions()) .execute() .get();
המשך
snapshot := client.Pipeline().Collection("cities"). FindNearest("embedding", []float64{1.5, 2.345}, firestore.PipelineDistanceMeasureEuclidean). Execute(ctx)
התנהגות
מדידת מרחק
בשלב find_nearest(...) נתמכות האפשרויות הבאות לחישוב המרחק בין וקטורים:
-
euclidean: מדידתeuclideanהמרחק בין הווקטורים. מידע נוסף זמין במאמר בנושא מרחק אוקלידי. -
cosine: השוואה בין וקטורים על סמך הזווית ביניהם, שמאפשרת למדוד דמיון שלא מבוסס על גודל הווקטורים. מומלץ להשתמש ב-dot_productעם וקטורים מנורמלים של יחידות במקום במרחק COSINE, שהוא שווה מבחינה מתמטית אבל עם ביצועים טובים יותר. מידע נוסף זמין במאמר בנושא דמיון קוסינוס. -
dot_product: דומה ל-cosineאבל מושפע מגודל הווקטורים. מידע נוסף זמין במאמר בנושא מכפלה סקלרית.
בחירת מדד המרחק
בהתאם לכך שכל הטמעות הווקטורים מנורמלות או לא, אפשר לקבוע באיזו מדידת מרחק להשתמש כדי למצוא את מדידת המרחק. הגודל (האורך) של הטמעת וקטורים מנורמלת הוא בדיוק 1.0.
בנוסף, אם אתם יודעים באיזה מדד מרחק נעשה שימוש באימון המודל, תוכלו להשתמש במדד הזה כדי לחשב את המרחק בין הטמעות הווקטורים.
נתונים מנורמלים
אם יש לכם מערך נתונים שבו כל ההטמעות הווקטוריות מנורמלות, כל שלושת מדדי המרחק יספקו את אותן תוצאות של חיפוש סמנטי. בעצם, למרות שכל מדד מרחק מחזיר ערך שונה, הערכים האלה מסודרים באותו אופן. כשמבצעים נורמליזציה של ההטבעות, בדרך כלל dot_product היא האפשרות הכי יעילה מבחינת חישובים, אבל ההבדל זניח ברוב המקרים. עם זאת, אם האפליקציה שלכם רגישה מאוד לביצועים, יכול להיות ש-dot_product יעזור לכם לכוונן את הביצועים.
נתונים לא מנורמלים
אם יש לכם מערך נתונים שבו הטבעות וקטוריות לא מנורמלות, לא נכון מבחינה מתמטית להשתמש ב-dot_product כמדד מרחק, כי מכפלה סקלרית לא מודדת מרחק. בהתאם לאופן שבו נוצרו ההטמעות ולסוג החיפוש המועדף, מדד המרחק cosine או euclidean יניב תוצאות חיפוש טובות יותר באופן סובייקטיבי ממדדי המרחק האחרים.
יכול להיות שתצטרכו לבצע ניסויים עם cosine או עם euclidean כדי לקבוע מה הכי מתאים לתרחיש השימוש שלכם.
לא בטוחים אם הנתונים מנורמלים או לא מנורמלים
אם אתם לא בטוחים אם הנתונים שלכם מנורמלים ואתם רוצים להשתמש ב-dot_product, מומלץ להשתמש ב-cosine במקום.
הפונקציה cosine דומה לפונקציה dot_product, אבל היא כוללת נורמליזציה.
המרחק שנמדד באמצעות cosine נע בין 0 ל-2. תוצאה שקרובה ל-0 מצביעה על כך שהווקטורים דומים מאוד.
הגבלת התוצאות
אפשר להגביל את מספר המסמכים שמוחזרים על ידי השאילתה באמצעות הגדרת השדה limit.
Node.js
const results = await db.pipeline()
.collection("cities")
.findNearest({
field: "embedding",
vectorValue: vector([1.5, 2.345]),
distanceMeasure: "euclidean",
limit: 10,
})
.execute();
אחזור המרחק הווקטורי המחושב
כדי לאחזר את המרחק הווקטורי המחושב, צריך להקצות שם למאפיין הפלט distance_field בשלב find_nearest(...), כמו בדוגמה הבאה:
לדוגמה, עבור האוסף הבא:
Node.js
await db.collection("cities").doc("SF").set({name: "San Francisco", embedding: vector([1.0, -1.0])});
await db.collection("cities").doc("TO").set({name: "Toronto", embedding: vector([5.0, -10.0])});
await db.collection("cities").doc("AT").set({name: "Atlantis", embedding: vector([2.0, -4.0])});
מבצעים חיפוש וקטורי עם פלט מבוקש distance_field:
Node.js
const results = await db.pipeline()
.collection("cities")
.findNearest({
field: "embedding",
vectorValue: vector([1.3, 2.345]),
distanceMeasure: "euclidean",
distanceField: "computedDistance",
})
.execute();
שמפיקות את המסמכים הבאים:
{name: "San Francisco", embedding: vector([1.0, -1.0]), computedDistance: 3.3584259705999178},
{name: "Atlantis", embedding: vector([2.0, -4.0]), computedDistance: 6.383496299051172},
{name: "Toronto", embedding: vector([5.0, -10.0]), computedDistance: 12.887553103673328}
מגבלות
כשעובדים עם הטמעות וקטוריות, חשוב לשים לב למגבלה הבאה:
- המימד המקסימלי של הטמעה שנתמך הוא 2048. כדי לאחסן אינדקסים גדולים יותר, משתמשים בצמצום ממדים.