בדף הזה מוסבר איך לבצע חיפוש שמשלב נתונים של טקסט מלא ונתונים שאינם טקסט.
ביצוע חיפוש משולב של טקסט מלא ושל תוכן שאינו טקסט
אינדקסים של חיפוש תומכים בחיפוש טקסט מלא, בהתאמה מדויקת, בעמודות מספריות ובעמודות JSON/JSONB. אפשר לשלב תנאים של טקסט ותנאים של לא-טקסט בפסקה WHERE, בדומה לשאילתות חיפוש מרובות עמודות. אופטימיזציית השאילתות מנסה לבצע אופטימיזציה של פרדיקטים שאינם טקסט באמצעות אינדקס חיפוש. אם זה לא אפשרי, Spanner מעריך את התנאי לכל שורה שתואמת לאינדקס החיפוש. עמודות שההפניה אליהן לא מאוחסנת באינדקס החיפוש מאוחזרות מהטבלה הבסיסית.
דוגמה:
GoogleSQL
CREATE TABLE Albums (
AlbumId STRING(MAX) NOT NULL,
Title STRING(MAX),
Rating FLOAT64,
Genres ARRAY<STRING(MAX)>,
Likes INT64,
Cover BYTES(MAX),
Title_Tokens TOKENLIST AS (TOKENIZE_FULLTEXT(Title)) HIDDEN,
Rating_Tokens TOKENLIST AS (TOKENIZE_NUMBER(Rating)) HIDDEN,
Genres_Tokens TOKENLIST AS (TOKEN(Genres)) HIDDEN
) PRIMARY KEY(AlbumId);
CREATE SEARCH INDEX AlbumsIndex
ON Albums(Title_Tokens, Rating_Tokens, Genres_Tokens)
STORING (Likes);
PostgreSQL
יש מגבלות מסוימות לתמיכה ב-PostgreSQL ב-Spanner:
- הפונקציה
spanner.tokenize_numberתומכת רק בסוגbigint. -
spanner.tokenלא תומך בטוקניזציה של מערכים.
CREATE TABLE albums (
albumid character varying NOT NULL,
title character varying,
rating bigint,
genres character varying NOT NULL,
likes bigint,
cover bytea,
title_tokens spanner.tokenlist AS (spanner.tokenize_fulltext(title)) VIRTUAL HIDDEN,
rating_tokens spanner.tokenlist AS (spanner.tokenize_number(rating)) VIRTUAL HIDDEN,
genres_tokens spanner.tokenlist AS (spanner.token(genres)) VIRTUAL HIDDEN,
PRIMARY KEY(albumid));
CREATE SEARCH INDEX albumsindex
ON albums(title_tokens, rating_tokens, genres_tokens)
INCLUDE (likes);
התנהגות השאילתות בטבלה הזו כוללת את הדברים הבאים:
Ratingו-Genresנכללים באינדקס החיפוש. Spanner מאיץ את התנאים באמצעות רשימות של פריטי אינדקס לחיפוש. ARRAY_INCLUDES_ANY,ARRAY_INCLUDES_ALLהן פונקציות GoogleSQL ולא נתמכות בניב PostgreSQL.SELECT Album FROM Albums WHERE Rating > 4 AND ARRAY_INCLUDES_ANY(Genres, ['jazz'])אפשר לשלב בשאילתה בין מילות חיבור, מילות הפרדה ושלילות בכל דרך, כולל שילוב בין פרדיקטים של טקסט מלא ופרדיקטים שאינם טקסט. השאילתה הזו מואצת באופן מלא על ידי אינדקס החיפוש.
SELECT Album FROM Albums WHERE (SEARCH(Title_Tokens, 'car') OR Rating > 4) AND NOT ARRAY_INCLUDES_ANY(Genres, ['jazz'])הפרמטר
Likesמאוחסן באינדקס, אבל הסכימה לא מבקשת מ-Spanner ליצור אינדקס של טוקנים לערכים האפשריים שלו. לכן, החיפוש המלא של הטקסט ב-Titleוהחיפוש של הטקסט ב-Ratingמואצים, אבל החיפוש ב-Likesלא מואץ. ב-Spanner, השאילתה מאחזרת את כל המסמכים עם המונח car ב-Titleודירוג גבוה מ-4, ואז היא מסננת מסמכים שלא קיבלו לפחות 1,000 לייקים. השאילתה הזו משתמשת בהרבה משאבים אם כמעט לכל האלבומים יש את המילה 'מכונית' בשם שלהם וכמעט לכולם יש דירוג של 5, אבל רק למעט אלבומים יש 1,000 לייקים. במקרים כאלה, יצירת אינדקסLikesבאופן דומה ל-Ratingחוסכת משאבים.GoogleSQL
SELECT Album FROM Albums WHERE SEARCH(Title_Tokens, 'car') AND Rating > 4 AND Likes >= 1000PostgreSQL
SELECT album FROM albums WHERE spanner.search(title_tokens, 'car') AND rating > 4 AND likes >= 1000הערך
Coverלא מאוחסן באינדקס. השאילתה הבאה מבצעת back join ביןAlbumsIndexל-Albumsכדי לאחזר אתCoverלכל האלבומים התואמים.GoogleSQL
SELECT AlbumId, Cover FROM Albums WHERE SEARCH(Title_Tokens, 'car') AND Rating > 4PostgreSQL
SELECT albumid, cover FROM albums WHERE spanner.search(title_tokens, 'car') AND rating > 4
המאמרים הבאים
- מידע נוסף על שאילתות חיפוש בטקסט מלא
- איך לדרג את תוצאות החיפוש
- איך מבצעים חיפוש של מחרוזת משנה
- איך מחלקים את תוצאות החיפוש לדפים
- איך מחפשים בכמה עמודות