בדף הזה מוסבר איך לדרג תוצאות של חיפושים בטקסט מלא ב-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) - הפופולריות(
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 | הגברה מדויקת |
| הגשר מעל המים הסוערים | הגברה מדויקת |
| גשר ("מעל מים סוערים" או missingterm) | הגברה מדויקת |
הגבלת עומק האחזור
אינדקסים של חיפוש מכילים בדרך כלל מיליוני מסמכים. לשאילתות שבהן יש למאפיינים סלקטיביות נמוכה, לא מעשי לדרג את כל התוצאות. בדרך כלל יש שתי מגבלות על שאילתות ניקוד:
- מגבלת עומק האחזור: מספר השורות המקסימלי שיינתן להן ניקוד.
- מגבלת גודל של קבוצת תוצאות: המספר המקסימלי של שורות שהשאילתה צריכה להחזיר (בדרך כלל גודל הדף).
אפשר להגביל את עומק האחזור של שאילתות באמצעות שאילתות משנה של SQL:
GoogleSQL
SELECT *
FROM (
SELECT AlbumId, Title_Tokens
FROM Albums
WHERE SEARCH(Title_Tokens, @p1)
ORDER BY ReleaseTimestamp DESC
LIMIT @retrieval_limit
)
ORDER BY SCORE(Title_Tokens, @p1)
LIMIT @page_size
PostgreSQL
בדוגמה הזו נעשה שימוש בפרמטרים של שאילתה $1, $2 ו-$3 שמשויכים לערכים שצוינו עבור title_query, retrieval_limit ו-page_size, בהתאמה.
SELECT *
FROM (
SELECT albumid, title_tokens
FROM albums
WHERE spanner.search(title_tokens, $1)
ORDER BY releasetimestamp DESC
LIMIT $2
) AS subquery
ORDER BY spanner.score(subquery.title_tokens, $1)
LIMIT $3
השיטה הזו יעילה במיוחד אם Spanner משתמש באות הדירוג החשובה ביותר כדי למיין את האינדקס.
המאמרים הבאים
- מידע נוסף על שאילתות חיפוש בטקסט מלא
- איך מבצעים חיפוש של מחרוזת משנה
- איך מחלקים את תוצאות החיפוש לדפים
- איך משלבים שאילתות של טקסט מלא עם שאילתות שאינן טקסט
- איך מחפשים בכמה עמודות