חיפוש באמצעות היבטים

בדף הזה מוסבר איך להשתמש בהיבטים בחיפוש טקסט מלא. במסגרת סינון אינטראקטיבי, פאסטה היא ערך סינון פוטנציאלי, והיא כוללת את מספר ההתאמות של המסנן הזה. באתרים עם האפשרות הזו, כשמזינים ביטוי לחיפוש, מקבלים רשימה של תוצאות בתפריט הניווט, ורשימה של היבטים שאפשר להשתמש בהם כדי לצמצם את תוצאות החיפוש, לצד מספר התוצאות שמתאימות לכל קטגוריה.

לדוגמה, אם משתמשים בשאילתה 'foo' כדי לחפש אלבומים, יכול להיות שיוצגו מאות תוצאות. אם יש היבט של ז'אנרים, אפשר לבחור לפי ז'אנרים כמו 'רוק (250)', 'R&B (50)' או 'פופ (150)'.

בחיפוש טקסט מלא ב-Spanner, אפשר להשתמש בביטויי SQL סטנדרטי ובפונקציות חיפוש טקסט מלא גם לסינון וגם לספירה מסוננת. לא צריך להשתמש בתחביר מיוחד כדי להשתמש בהיבטים.

הוספת היבטים לשימוש בחיפושים של טקסט מלא

בדוגמה הבאה נוצרת טבלה של אלבומים, והכותרת של כל אלבום עוברת טוקניזציה. הטבלה הזו משמשת לדוגמאות בדף הזה.

GoogleSQL

CREATE TABLE Albums (
  AlbumId INT64 NOT NULL,
  Title STRING(MAX),
  Rating INT64,
  Genres ARRAY<STRING(MAX)>,
  Likes INT64 NOT NULL,
  Title_Tokens TOKENLIST AS (TOKENIZE_FULLTEXT(Title)) HIDDEN,
) PRIMARY KEY(AlbumId);

PostgreSQL

CREATE TABLE albums (
  albumid bigint NOT NULL,
  title text,
  rating bigint,
  genres text[],
  likes bigint NOT NULL,
  title_tokens spanner.TOKENLIST GENERATED ALWAYS AS (spanner.TOKENIZE_FULLTEXT(Title)) VIRTUAL HIDDEN,
PRIMARY KEY(albumid));

יוצרים אינדקס חיפוש ב-Title_Tokens. אופציונלי, אפשר לאחסן את Title, Genres ואת Rating באינדקס החיפוש כדי להימנע מחיבור חוזר לטבלת הבסיס בזמן חישוב הפנים.

GoogleSQL

CREATE SEARCH INDEX AlbumsIndex
ON Albums (Title_Tokens)
STORING (Title, Genres, Rating)
ORDER BY Likes DESC;

PostgreSQL

CREATE SEARCH INDEX albumsindex
ON albums (title_tokens)
INCLUDE (title, genres, rating)
ORDER BY likes DESC

בדוגמה הזו, מוסיפים את הנתונים הבאים לטבלה.

GoogleSQL

INSERT INTO Albums (AlbumId, Title, Rating, Genres, Likes) VALUES
(1, "The Foo Strike Again", 5, ["Rock", "Alternative"], 600),
(2, "Who are the Who?", 5, ["Progressive", "Indie"], 200),
(3, "No Foo For You", 4, ["Metal", "Alternative"], 50)

PostgreSQL

INSERT INTO albums (albumid, title, rating, genres, likes) VALUES
(1, 'The Foo Strike Again', 5,'{"Rock", "Alternative"}', 600),
(2, 'Who are the Who?', 5,'{"Progressive", "Indie"}', 200),
(3, 'No Foo For You', 4,'{"Metal", "Alternative"}', 50)

אחזור ערכי ספירה של היבט יחיד

בדוגמה הזו מוסבר איך לבצע ספירה של פנים ב-Rating facet. הפונקציה מבצעת חיפוש טקסט של 'foo' בעמודה Title_Tokens בטבלה Albums.

GoogleSQL

SELECT Rating, COUNT(*) AS result_count
FROM Albums
WHERE SEARCH(Title_Tokens, "foo")
GROUP BY Rating
ORDER BY Rating DESC

| Rating | result_count |
|--------|--------------|
| 5      | 1            |
| 4      | 1            |

PostgreSQL

SELECT rating, COUNT(*) AS result_count
FROM albums
WHERE spanner.SEARCH(title_tokens, 'foo')
GROUP BY rating
ORDER BY rating DESC;

| rating | result_count |
|--------|--------------|
| 5      | 1            |
| 4      | 1            |

אחזור ערכי ספירה של כמה היבטים

בדוגמה הזו מוצגים השלבים לביצוע ספירת פנים בכמה פנים. הוא מבצע את הפעולות הבאות:

  1. שליפת תוצאות החיפוש הראשוניות: הפונקציה מבצעת חיפוש טקסט של foo בעמודה Title_Tokens בטבלה Albums.
  2. חישוב מספר התוצאות בכל פן: המערכת מחשבת את מספר התוצאות בפנים Rating ו-Genres.

GoogleSQL

WITH search_results AS (
  SELECT AlbumId, Title, Genres, Rating, Likes
  FROM Albums
  WHERE SEARCH(Title_Tokens, "foo")
  ORDER BY Likes DESC, AlbumId
  LIMIT 10000
)

SELECT
-- Result set #1: First page of search results
ARRAY(
  SELECT AS STRUCT *
  FROM search_results
  ORDER BY Likes DESC, AlbumId
  LIMIT 50
) as result_page,
-- Result set #2: Number of results by rating
ARRAY(
  SELECT AS STRUCT Rating, COUNT(*) as result_count
  FROM search_results
  GROUP BY Rating
  ORDER BY result_count DESC, Rating DESC
) as rating_counts,
-- Result set #3: Number of results for top 5 genres
ARRAY(
  SELECT AS STRUCT genre, COUNT(*) as result_count
  FROM search_results
  JOIN UNNEST(Genres) genre
  GROUP BY genre
  ORDER BY result_count DESC, genre
  LIMIT 5
) as genres_counts

PostgreSQL

WITH search_results AS (
  SELECT albumid, title, genres, rating, likes
  FROM albums
  WHERE spanner.SEARCH(title_tokens, 'foo')
  ORDER BY likes DESC, albumid
  LIMIT 10000
)

-- The pattern ARRAY(SELECT TO_JSONB ...) enables returning multiple nested
-- result sets in the same query.
SELECT
  -- Result set #1: First page of search results
  ARRAY(
  SELECT JSONB_BUILD_OBJECT(
    'albumid', albumid,
    'title', title,
    'genres', genres,
    'rating', rating,
    'likes', likes
    )
  FROM search_results
  ORDER BY likes DESC, albumid
  LIMIT 50
) as result_page,
-- Result set #2: Number of results by rating
ARRAY(
  SELECT JSONB_BUILD_OBJECT(
    'rating', rating,
    'result_count', COUNT(*)
    )
  FROM search_results
  GROUP BY rating
  ORDER BY COUNT(*) DESC, rating DESC
) as rating_counts,
-- Result set #3: Number of results for top 5 genres
ARRAY(
  SELECT JSONB_BUILD_OBJECT(
    'genre', genre,
    'result_count', COUNT(*)
    )
  FROM
    search_results,
    UNNEST(genres) AS genre
  GROUP BY genre
  ORDER BY COUNT(*) DESC, genre
  LIMIT 5
) as genres_counts

באופן ספציפי, הדוגמה הזו מבצעת את הפעולות הבאות:

  • WITH search_results AS (...) אוסף קבוצה גדולה של תוצאות חיפוש ראשוניות לשימוש בדף הראשון של התוצאות ולחישובים של היבטים.
  • SEARCH(Title_Tokens, "foo") היא שאילתת החיפוש הראשית.
  • LIMIT 10000 מגביל את עלות החיפוש על ידי צמצום קבוצת התוצאות ל-10,000. בחיפושים רחבים מאוד שעשויים להחזיר מיליוני תוצאות, חישוב מדויק של מספר התוצאות בכל פן על מערך הנתונים כולו עלול להיות יקר. הגבלת תוצאות החיפוש מאפשרת לשאילתה לספק במהירות ספירות משוערות (גבול תחתון) של מאפיינים. המשמעות היא שהמספרים משקפים לפחות את מספר התוצאות הזה, אבל יכול להיות שיש עוד תוצאות תואמות מעבר למגבלה של 10,000.
  • שאילתת המשנה result_page מפיקה את הדף הראשון של תוצאות החיפוש שמוצגות למשתמש. היא בוחרת רק את 50 הרשומות הראשונות מתוך search_results, לפי הסדר של Likes ושל AlbumId. זה מה שהמשתמש רואה בהתחלה.
  • שאילתת המשנה rating_counts מחשבת את מספר ההיטים של ההיבטים עבור Rating. הפונקציה מקבצת את כל הרשומות ב-search_results לפי Rating וסופרת כמה תוצאות נכללות בכל קטגוריית דירוג.
  • שאילתת המשנה genres_counts מחשבת את מספר ההיבטים של Genres. מכיוון שזהו מערך, צריך להשתמש בפונקציה join עם UNNEST(Genres) כדי להתייחס לכל ז'אנר במערך כשורה נפרדת לצורך הספירה.

אחזור דפים עוקבים

כשמבצעים שאילתה לדפים עוקבים אחרי שאילתת הפנים הראשונית, אפשר לעשות שימוש חוזר בספירות הפנים שהוחזרו מהדף הראשון.

מידע נוסף על הגדרת מעברי עמוד זמין במאמר שימוש בהגדרת מעברי עמוד שמבוססת על מפתח.