בדף הזה מוסבר איך למצוא שכנים קרובים משוערים (ANN) ולשאילת הטמעות של וקטורים באמצעות פונקציות המרחק של ANN.
כשמערך הנתונים קטן, אפשר להשתמש בשיטה K-nearest neighbors (KNN) כדי למצוא את הווקטורים המדויקים הכי קרובים. עם זאת, ככל שמערך הנתונים גדל, גם זמן האחזור והעלות של חיפוש KNN עולים. אתם יכולים להשתמש ב-ANN כדי למצוא את השכנים הקרובים ביותר (k-nearest neighbors) עם זמן אחזור ועלות נמוכים משמעותית.
בחיפוש ANN, הווקטורים שמוחזרים לא מייצגים את k השכנים הקרובים ביותר כי חיפוש ANN מחשב מרחקים משוערים, ויכול להיות שהוא לא בודק את כל הווקטורים במערך הנתונים. לפעמים, המערכת מחזירה כמה וקטורים שלא נכללים ב-k השכנים הקרובים ביותר. התופעה הזו נקראת אובדן היזכרות. כמה אובדן של זיכרון הוא סביר בעיניכם? זה תלוי בתרחיש השימוש, אבל ברוב המקרים, אובדן קל של זיכרון בתמורה לשיפור הביצועים של מסד הנתונים הוא פשרה מקובלת.
פרטים נוספים על פונקציות המרחק המשוער שנתמכות ב-Spanner זמינים בדפי העיון הבאים לגבי הדיאלקט של מסד הנתונים:
- GoogleSQL
- PostgreSQL
שאילתות הטמעה של וקטורים
Spanner מאיץ חיפושים של וקטורים של שכן קרוב משוער (ANN) באמצעות אינדקס וקטורי. אפשר להשתמש באינדקס וקטורי כדי לשלוח שאילתות להטמעות וקטוריות. כדי לשלוח שאילתות לגבי הטמעות וקטוריות, צריך קודם ליצור אינדקס וקטורי. לאחר מכן תוכלו להשתמש באחת משלוש פונקציות המרחק המשוער כדי למצוא את ה-ANN.
ההגבלות שחלות על שימוש בפונקציות של מרחק משוער כוללות את ההגבלות הבאות:
- פונקציית המרחק המשוער צריכה לחשב את המרחק בין עמודת הטמעה לבין ביטוי קבוע (לדוגמה, פרמטר או ערך מילולי).
- הפלט של פונקציית המרחק המשוער חייב לשמש כערך היחיד למיון בסעיף
ORDER BY, וחייבים לצייןLIMITאחריORDER BY. - השאילתה צריכה לסנן באופן מפורש שורות שלא נכללות באינדקס. ברוב המקרים, המשמעות היא שהשאילתה צריכה לכלול פסקה
WHERE <column_name> IS NOT NULLשתואמת להגדרת אינדקס הווקטורים, אלא אם העמודה כבר מסומנת כ-NOT NULLבהגדרת הטבלה.
רשימה מפורטת של המגבלות מופיעה בדף העזר בנושא פונקציית המרחק המשוער.
דוגמאות
נניח שיש לכם טבלה Documents עם עמודה DocEmbedding של הטמעות טקסט שחושבו מראש מהעמודה DocContents bytes, ועמודה NullableDocEmbedding שמלאה בנתונים ממקורות אחרים, שיכולים להיות null.
GoogleSQL
CREATE TABLE Documents (
UserId INT64 NOT NULL,
DocId INT64 NOT NULL,
Author STRING(1024),
DocContents BYTES(MAX),
DocEmbedding ARRAY<FLOAT32> NOT NULL,
NullableDocEmbedding ARRAY<FLOAT32>,
WordCount INT64
) PRIMARY KEY (UserId, DocId);
PostgreSQL
CREATE TABLE documents (
user_id bigint not null,
doc_id bigint not null,
author varchar(1024),
doc_contents bytea,
doc_embedding float4[] not null,
nullable_doc_embedding float4[],
word_count bigint,
PRIMARY KEY (user_id, doc_id)
);
כדי לחפש את 100 הווקטורים הקרובים ביותר ל-[1.0, 2.0, 3.0], מציינים אחת מאפשרויות החיפוש הבאות בפונקציית המרחק המשוער:
-
num_leaves_to_search: מספר העלים לחיפוש. הערך חייב להיות מספר שלם חיובי. -
pct_leaves_to_search: אחוז העלים לחיפוש. הערך חייב להיות מספר עשרוני בין0.0ל-100.0עם נקודה עשרונית מפורשת (לדוגמה,10.0). יכול להיות שמדדי וקטור שנוצרו לפני נובמבר 2025 לא יתמכו באפשרות החיפוש הזו.
אי אפשר לציין את שתי האפשרויות באותה פונקציה של מרחק משוער.
אפשרות 1. שימוש באפשרות החיפוש num_leaves_to_search
GoogleSQL
SELECT DocId
FROM Documents
WHERE WordCount > 1000
ORDER BY APPROX_EUCLIDEAN_DISTANCE(
ARRAY<FLOAT32>[1.0, 2.0, 3.0], DocEmbedding,
options => JSON '{"num_leaves_to_search": 10}')
LIMIT 100
PostgreSQL
SELECT doc_id
FROM documents
WHERE word_count > 1000
ORDER BY spanner.approx_euclidean_distance(
ARRAY[1.0, 2.0, 3.0]::float4[], doc_embedding,
options=>jsonb'{"num_leaves_to_search": 10}'
)
LIMIT 100;
אפשרות 2. שימוש באפשרות החיפוש pct_leaves_to_search
GoogleSQL
SELECT DocId
FROM Documents
WHERE WordCount > 1000
ORDER BY APPROX_EUCLIDEAN_DISTANCE(
ARRAY<FLOAT32>[1.0, 2.0, 3.0], DocEmbedding,
options => JSON '{"pct_leaves_to_search": 10.0}')
LIMIT 100
PostgreSQL
SELECT doc_id
FROM documents
WHERE word_count > 1000
ORDER BY spanner.approx_euclidean_distance(
ARRAY[1.0, 2.0, 3.0]::float4[], doc_embedding,
options=>jsonb'{"pct_leaves_to_search": 10.0}'
)
LIMIT 100;
כדי לחפש את 100 הווקטורים הקרובים ביותר להטמעה שנוצרה על ידי ביטוי SQL, משתמשים בתבנית הבאה. בדוגמה הזו, השאילתה מחפשת את המסמכים שהכי דומים להטמעה של UserId = 1 ו-DocId = 1:
GoogleSQL
WITH emb AS (
SELECT DocEmbedding AS value
FROM Documents
WHERE UserId = 1 AND DocId = 1
LIMIT 1
)
SELECT DocId
FROM Documents, emb
ORDER BY APPROX_EUCLIDEAN_DISTANCE(
emb.value, DocEmbedding,
options => JSON '{"num_leaves_to_search": 10}')
LIMIT 100
PostgreSQL
SELECT documents.doc_id
FROM
documents,
(
SELECT doc_embedding AS value
FROM documents
WHERE user_id = 1 AND doc_id = 1
LIMIT 1
) vector
WHERE documents.doc_embedding IS NOT NULL
ORDER BY spanner.APPROX_EUCLIDEAN_DISTANCE(documents.doc_embedding,
vector.value, options=>'{"num_leaves_to_search": 10}'::jsonb)
LIMIT 100
אם עמודת ההטמעה מאפשרת ערכי Null:
GoogleSQL
SELECT DocId
FROM Documents
WHERE NullableDocEmbedding IS NOT NULL AND WordCount > 1000
ORDER BY APPROX_EUCLIDEAN_DISTANCE(
ARRAY<FLOAT32>[1.0, 2.0, 3.0], NullableDocEmbedding,
options => JSON '{"num_leaves_to_search": 10}')
LIMIT 100
PostgreSQL
SELECT doc_id
FROM documents
WHERE nullable_doc_embedding IS NOT NULL AND word_count > 1000
ORDER BY spanner.approx_euclidean_distance(
ARRAY[1.0, 2.0, 3.0]::float4[], nullable_doc_embedding,
options=>jsonb'{"num_leaves_to_search": 10}'
)
LIMIT 100;
הוספת המרחק לתוצאות השאילתה
בדוגמאות הקודמות, נעשה שימוש במרחק ANN כדי לסדר את תוצאות השאילתה, אבל הוא לא מוצג בתוצאות האלה. כדי להוסיף את המרחק לתוצאות, צריך להציב את פונקציית המרחק בסעיף SELECT ולהגדיר לה כינוי, ואז להשתמש בכינוי הזה כמפתח הסדר היחיד בסעיף ORDER BY.
דוגמאות
GoogleSQL
SELECT DocId,
APPROX_EUCLIDEAN_DISTANCE(
ARRAY<FLOAT32>[1.0, 2.0, 3.0], NullableDocEmbedding,
options => JSON '{"num_leaves_to_search": 10}') AS distance
FROM Documents
WHERE NullableDocEmbedding IS NOT NULL AND WordCount > 1000
ORDER BY distance
LIMIT 100
PostgreSQL
SELECT doc_id,
spanner.approx_euclidean_distance(
ARRAY[1.0, 2.0, 3.0]::float4[], nullable_doc_embedding,
options=>jsonb'{"num_leaves_to_search": 10}'
) AS distance
FROM documents
WHERE nullable_doc_embedding IS NOT NULL AND word_count > 1000
ORDER BY distance
LIMIT 100;
המאמרים הבאים
מידע נוסף על פונקציות לחישוב מרחק משוער ב-GoogleSQL וב-PostgreSQL
מידע נוסף על הצהרות אינדקס ל-GoogleSQL
VECTOR INDEXול-PostgreSQLINDEXכדאי לנסות את תחילת העבודה עם Spanner Vector Search כדי לראות דוגמה מפורטת לשימוש ב-ANN.