בדף הזה מוסבר איך לדרג תוצאות של חיפושים בטקסט מלא ב-Spanner.
Spanner תומך בחישוב ציון רלוונטיות לנושא, שמספק אבן בניין ליצירת פונקציות דירוג מתוחכמות. הציונים האלה מחושבים על סמך הרלוונטיות של תוצאה לשאילתה, בהתבסס על התדירות של מונח השאילתה ואפשרויות אחרות שניתנות להתאמה אישית.
בדוגמה הבאה אפשר לראות איך מבצעים חיפוש מדורג באמצעות הפונקציה SCORE:
GoogleSQL
SELECT AlbumId
FROM Albums
WHERE SEARCH(AlbumTitle_Tokens, "fifth symphony")
ORDER BY SCORE(AlbumTitle_Tokens, "fifth symphony") DESC
PostgreSQL
בדוגמה הזו נעשה שימוש ב-spanner.search עם spanner.score.
SELECT albumid
FROM albums
WHERE spanner.search(albumtitle_tokens, 'fifth symphony')
ORDER BY spanner.score(albumtitle_tokens, 'fifth symphony') DESC
הקצאת ציון למונחי שאילתות באמצעות הפונקציה SCORE
הפונקציה SCORE
מחשבת ציון לכל מונח בשאילתה, ואז משלבת את הציונים. הניקוד לכל מונח מבוסס בערך על תדירות המונח – תדירות מסמך הפוכה
(TF/IDF). הניקוד הוא רכיב אחד בסדר הסופי של הרשומה. השאילתה משלבת את זה עם אותות אחרים, כמו עדכניות שמשפיעה על ניקוד הרלוונטיות לנושא.
ביישום הנוכחי, החלק IDF של TF/IDF זמין רק כשמשתמשים ב-enhance_query=>true. הוא מחשב את התדירות היחסית של מילים על סמך מאגר הנתונים המלא של האינטרנט שמשמש את חיפוש Google, ולא על סמך אינדקס חיפוש ספציפי. אם לא מפעילים את שיפור השאילתה, הניקוד מבוסס רק על רכיב תדירות המונח (TF) (כלומר, מונח ה-IDF מוגדר כ-1).
הפונקציה SCORE מחזירה ערכים שמשמשים כציוני רלוונטיות ש-Spanner משתמש בהם כדי לקבוע סדר מיון. אין להם משמעות עצמאית. ככל שהציון גבוה יותר, כך ההתאמה לשאילתה טובה יותר.
בדרך כלל הארגומנטים כמו query ו-enhance_query זהים בפונקציות SEARCH ו-SCORE כדי להבטיח עקביות באחזור ובדירוג.
הדרך המומלצת לעשות את זה היא להשתמש בארגומנטים האלה עם פרמטרים של שאילתה ולא עם מחרוזות מילוליות, ולציין את אותם פרמטרים של שאילתה בפונקציות SEARCH ו-SCORE.
הוספת ניקוד למספר עמודות
ב-Spanner נעשה שימוש בפונקציה SCORE כדי לתת ניקוד לכל שדה בנפרד. לאחר מכן, השאילתה משלבת את הציונים הנפרדים האלה. דרך נפוצה לעשות את זה היא לסכם את הציונים האישיים ואז להגדיל אותם בהתאם למשקלים של השדות שסופקו על ידי המשתמש (שמסופקים באמצעות פרמטרים של שאילתת SQL).
לדוגמה, השאילתה הבאה משלבת את הפלט של שתי פונקציות SCORE:
GoogleSQL
SELECT AlbumId
FROM Albums
WHERE SEARCH(Title_Tokens, @p1) OR SEARCH(Studio_Tokens, @p2)
ORDER BY SCORE(Title_Tokens, @p1) * @titleweight + SCORE(Studio_Tokens, @p2) * @studioweight
LIMIT 25
PostgreSQL
בדוגמה הזו נעשה שימוש בפרמטרים של שאילתה $1 ו-$2 שמשויכים לערכים fifth symphony ו-blue note, בהתאמה.
SELECT albumid
FROM albums
WHERE spanner.search(title_tokens, $1) OR spanner.search(studio_tokens, $2)
ORDER BY spanner.score(title_tokens, $1) * $titleweight
+ spanner.score(studio_tokens, $2) * $studioweight
LIMIT 25
בדוגמה הבאה מוסיפים שני פרמטרים של הגברת עוצמה:
- עדכניות (
FreshnessBoost) מעלה את הציון ב-(1 + @freshnessweight * GREATEST(0, 30 - DaysOld) / 30) - הפונקציה Popularity(
PopularityBoost) מגדילה את הניקוד על ידי הכפלה שלו בפקטור(1 + IF(HasGrammy, @grammyweight, 0).
כדי שהשאילתה תהיה קלה יותר לקריאה, נעשה בה שימוש באופרטור WITH.
GoogleSQL
SELECT AlbumId
FROM Albums
WHERE SEARCH(Title_Tokens, @p1) OR SEARCH(Studio_Tokens, @p2)
ORDER BY WITH(
TitleScore AS SCORE(Title_Tokens, @p1) * @titleweight,
StudioScore AS SCORE(Studio_Tokens, @p2) * @studioweight,
DaysOld AS (UNIX_MICROS(CURRENT_TIMESTAMP()) - ReleaseTimestamp) / 8.64e+10,
FreshnessBoost AS (1 + @freshnessweight * GREATEST(0, 30 - DaysOld) / 30),
PopularityBoost AS (1 + IF(HasGrammy, @grammyweight, 0)),
(TitleScore + StudioScore) * FreshnessBoost * PopularityBoost)
LIMIT 25
PostgreSQL
בדוגמה הזו נעשה שימוש בפרמטרים של שאילתה $1, $2, $3, $4, $5 ו-$6
שמקושרים לערכים שצוינו עבור titlequery, studioquery, titleweight, studioweight, grammyweight ו-freshnessweight, בהתאמה.
SELECT albumid
FROM
(
SELECT
albumid,
spanner.score(title_tokens, $1) * $3 AS titlescore,
spanner.score(studio_tokens, $2) * $4 AS studioscore,
(extract(epoch FROM current_timestamp) * 10e+6 - releasetimestamp) / 8.64e+10 AS daysold,
(1 + CASE WHEN hasgrammy THEN $5 ELSE 0 END) AS popularityboost
FROM albums
WHERE spanner.search(title_tokens, $1) OR spanner.search(studio_tokens, $2)
) AS subquery
ORDER BY (subquery.TitleScore + subquery.studioscore)
* (1 + $6 * greatest(0, 30 - subquery.daysold) / 30) * subquery.popularityboost
LIMIT 25
TOKENLIST_CONCAT
יכולה לשמש גם לחיפוש ולדירוג כדי לפשט שאילתות כשזה מתאים.
GoogleSQL
SELECT AlbumId
FROM Albums
WHERE SEARCH(TOKENLIST_CONCAT([Title_Tokens, Studio_Tokens]), @p)
ORDER BY SCORE(TOKENLIST_CONCAT([Title_Tokens, Studio_Tokens]), @p)
LIMIT 25
PostgreSQL
בדוגמה הזו נעשה שימוש ב-spanner.tokenlist_concat.
פרמטר השאילתה $1 קשור ל-'blue note'.
SELECT albumid
FROM albums
WHERE spanner.search(spanner.tokenlist_concat(ARRAY[title_tokens, studio_tokens]), $1)
ORDER BY spanner.score(spanner.tokenlist_concat(ARRAY[title_tokens, studio_tokens]), $1)
LIMIT 25
שיפור ההתאמות של הזמנות לשאילתות
Spanner מחיל הגברה כפלית על הפלט של הפונקציה SCORE עבור ערכים שמכילים את מונחי השאילתה באותו סדר שבו הם מופיעים בשאילתה. יש שתי גרסאות של ההגדרה הזו: התאמה חלקית והתאמה מדויקת. הגברת התאמה חלקית מתרחשת במקרים הבאים:
- התג
TOKENLISTמכיל את כל המונחים המקוריים בשאילתה. - האסימונים צמודים זה לזה, ובאותו סדר שבו הם מופיעים בשאילתה.
יש כללים מיוחדים מסוימים לגבי מילות קישור, שלילות וצירופי מילים:
- אי אפשר להגדיר לשאילתה עם שלילה הגברה של התאמה חלקית.
- שאילתה עם מילת חיבור מקבלת דחיפה אם חלק ממילת החיבור מופיע במיקומים המתאימים.
- שאילתה עם ביטוי מקבלת דחיפה אם הביטוי מופיע ב-
TOKENLIST, והמונח שמשמאל לביטוי בשאילתה מופיע משמאל לביטוי ב-TOKENLIST, וכך גם לגבי המונח שמימין לביטוי.
Spanner מחיל חיזוק של התאמה מדויקת כשכל הכללים הקודמים מתקיימים, והטוקנים הראשון והאחרון בשאילתה הם הטוקנים הראשון והאחרון במסמך.
מסמך לדוגמה: Bridge Over Troubled Water
| שאילתה | ההגברה הוחלה |
|---|---|
| Bridge Troubled | ללא הגדלה |
| גשר מעל – מים אחרים | ללא הגדלה |
| Bridge (Over OR Troubled) Water | ללא הגדלה |
| Bridge Over | הגדלה חלקית |
| Bridge Over (Troubled OR Water) | הגדלה חלקית |
| Bridge Over Troubled Water | הגברה מדויקת |
| הגשר מעל המים הסוערים | הגברה מדויקת |
| Bridge ("Over Troubled" OR missingterm) Water | הגברה מדויקת |
גרסאות של כלי הניקוד
האלגוריתם של מערכת הניקוד מתעדכן מדי פעם. בכל גרסה יש חבילה של שיפורים באלגוריתם הניקוד. רשימה מפורטת של ההבדלים בין הגרסאות זמינה במאמר בנושא גרסאות של כלי הניקוד.
אתם יכולים להגדיר את גרסת הכלי לחישוב ניקוד כברירת מחדל למסד הנתונים, או לציין גרסה לשאילתה ספציפית.
הגדרת גרסת ברירת המחדל של כלי הניקוד במסד הנתונים
אפשר להגדיר את גרסת ברירת המחדל של אלגוריתם הניקוד למסד הנתונים. האפשרות הזו קובעת באיזו גרסה של אלגוריתם הניקוד Spanner משתמש כשקוראים לפונקציה SCORE בלי אפשרות ניקוד version מפורשת.
GoogleSQL
מגדירים את האפשרות score_version מסד נתונים:
ALTER DATABASE database_name SET OPTIONS (score_version = 2)
PostgreSQL
מגדירים את האפשרות spanner.score_version מסד נתונים:
ALTER DATABASE database_name SET "spanner.score_version" = 2
הערכים התקינים לאפשרות מסד הנתונים הם 1 או 2. אם הפרמטר version מופיע בבקשה, הוא מבטל את גרסת ברירת המחדל של מסד הנתונים.
שינוי גרסת הכלי לניקוד לכל שאילתה
אפשר לשנות את גרסת ברירת המחדל של הדירוג לשאילתה ספציפית באמצעות הפרמטר version בארגומנט options של הפונקציה SCORE. אם שאילתה
מגדירה גרסה של כלי לדירוג, היא מבטלת את הגרסה שמוגדרת כברירת מחדל במסד הנתונים.
בדוגמה הבאה מוחלפת גרסת הכלי לחישוב ניקוד ברירת המחדל על ידי ציון version בפרמטר options:
GoogleSQL
SELECT AlbumId
FROM Albums
WHERE SEARCH(AlbumTitle_Tokens, @query)
ORDER BY SCORE(
AlbumTitle_Tokens,
@query,
options=>JSON '{"version": 2}'
) DESC
PostgreSQL
בדוגמה הזו נעשה שימוש בפרמטר השאילתה $1 שמשויך למחרוזת השאילתה.
SELECT albumid
FROM albums
WHERE spanner.search(albumtitle_tokens, $1)
ORDER BY spanner.score(
albumtitle_tokens,
$1,
options => '{"version": 2}'::jsonb
) DESC
הגבלת עומק האחזור
אינדקסים של חיפושים מכילים בדרך כלל מיליוני מסמכים. בשאילתות שבהן יש פרדיקטים עם סלקטיביות נמוכה, לא מעשי לדרג את כל התוצאות. בדרך כלל יש שתי מגבלות על שאילתות ניקוד:
- מגבלת עומק האחזור: מספר השורות המקסימלי לניקוד.
- מגבלת גודל של קבוצת תוצאות: המספר המקסימלי של שורות שהשאילתה צריכה להחזיר (בדרך כלל גודל הדף).
אפשר להגביל את עומק האחזור של שאילתות באמצעות שאילתות משנה של SQL:
GoogleSQL
SELECT AlbumId
FROM
(
SELECT AlbumId, SCORE(Title_Tokens, @p1) AS score
FROM Albums
WHERE SEARCH(Title_Tokens, @p1)
ORDER BY ReleaseTimestamp DESC
LIMIT @retrieval_limit
)
ORDER BY score DESC
LIMIT @page_size
PostgreSQL
בדוגמה הזו נעשה שימוש בפרמטרים של שאילתה $1, $2 ו-$3 שמשויכים לערכים שצוינו עבור title_query, retrieval_limit ו-page_size, בהתאמה.
SELECT albumid
FROM
(
SELECT albumid, spanner.score(title_tokens, $1) AS score
FROM albums
WHERE spanner.search(title_tokens, $1)
ORDER BY releasetimestamp DESC
LIMIT $2
) AS subquery
ORDER BY score DESC
LIMIT $3
השיטה הזו יעילה במיוחד אם Spanner משתמש באות הדירוג הכי חשוב כדי למיין את האינדקס.
המאמרים הבאים
- מידע נוסף על שאילתות חיפוש של טקסט מלא
- איך מבצעים חיפוש של מחרוזת משנה
- איך מחלקים את תוצאות החיפוש לדפים
- איך משלבים שאילתות של טקסט מלא עם שאילתות של טקסט חלקי
- איך מחפשים בכמה עמודות