חיפוש בכמה עמודות באינדקסים של חיפוש

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

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

לדוגמה, נניח את הסכימה הבאה:

GoogleSQL

CREATE TABLE Albums (
  AlbumId STRING(MAX) NOT NULL,
  Title STRING(MAX),
  Studio STRING(MAX),
  Title_Tokens TOKENLIST AS (TOKENIZE_FULLTEXT(Title)) HIDDEN,
  Studio_Tokens TOKENLIST AS (TOKENIZE_FULLTEXT(Studio)) HIDDEN
) PRIMARY KEY(AlbumId);

CREATE SEARCH INDEX AlbumsIndex ON Albums(Title_Tokens, Studio_Tokens);

PostgreSQL

CREATE TABLE albums (
  albumid character varying NOT NULL,
  title character varying,
  studio character varying,
  title_tokens spanner.tokenlist
      GENERATED ALWAYS AS (TOKENIZE_FULLTEXT(title)) VIRTUAL HIDDEN,
  studio_tokens spanner.tokenlist
      GENERATED ALWAYS AS (TOKENIZE_FULLTEXT(studio)) VIRTUAL HIDDEN,
) PRIMARY KEY(albumid);

CREATE SEARCH INDEX albumsindex ON albums(title_tokens, studio_tokens);

שאילתה יכולה לחפש עכשיו בשני שדות: Title_Tokens ו-Studio_Tokens.

GoogleSQL

SELECT AlbumId
FROM Albums
WHERE SEARCH(Title_Tokens, "fifth symphony")
  AND SEARCH(Studio_Tokens, "Blue Note Studio")

PostgreSQL

SELECT albumid
FROM albums
WHERE spanner.search(title_tokens, 'fifth symphony')
  AND spanner.search(studio_tokens, 'Blue Note Studio')

‫Spanner תומך בשאילתות חיפוש מרובות עמודות בשילוב עם אופרטורים של חיבור, הפרדה ושלילה בסעיף WHERE. אפשר להשתמש בכל סוגי השאילתות הבאים עם אינדקס חיפוש:

  • חיבור: חיפוש מסמכים שבהם Title מכיל את המונח car וגם Studio מכיל את המונח sun.

    GoogleSQL

    SELECT AlbumId
    FROM Albums
    WHERE SEARCH(Title_Tokens, 'car') AND SEARCH(Studio_Tokens, 'sun')
    

    PostgreSQL

    SELECT albumid
    FROM albums
    WHERE spanner.search(title_tokens, 'car') AND spanner.search(studio_tokens, 'sun')
    
  • איחוד: חיפוש מסמכים שבהם Title מכיל את המילה car או ש-Studio מכיל את המילה sun

    GoogleSQL

    SELECT AlbumId
    FROM Albums
    WHERE SEARCH(Title_Tokens, 'car') OR SEARCH(Studio_Tokens, 'sun')
    

    PostgreSQL

    SELECT albumid
    FROM albums
    WHERE spanner.search(title_tokens, 'car') OR spanner.search(studio_tokens, 'sun')
    
  • שלילה: חיפוש כל המסמכים שבהם Title לא מכיל את המונח 'מכונית'.

    GoogleSQL

    SELECT AlbumId
    FROM Albums
    WHERE NOT SEARCH(Title_Tokens, 'car')
    

    PostgreSQL

    SELECT albumid
    FROM albums
    WHERE NOT spanner.search(title_tokens, 'car')
    

    השפה rquery יכולה לבצע את אותו סוג של חיפושים:

    GoogleSQL

    SELECT AlbumId
    FROM Albums
    WHERE SEARCH(Title_Tokens, '-car')
    

    PostgreSQL

    SELECT albumid
    FROM albums
    WHERE spanner.search(title_tokens, '-car')
    

    בשני הטפסים מסננים מסמכים שבהם Title הוא NULL. פונקציות של טוקניזציה וחיפוש מוגדרות להחזרת NULL בקלט NULL. ב-SQL,‏ NOT NULL מוגדר כ-NULL.

בנוסף, אפשר להפנות לאותה עמודה TOKENLIST כמה פעמים.

GoogleSQL

SELECT AlbumId
FROM Albums
WHERE (SEARCH(Title_Tokens, 'car') OR SEARCH(Studio_Tokens, 'sun'))
  AND (SEARCH(Title_Tokens, 'guy') OR SEARCH(Studio_Tokens, electric))

PostgreSQL

SELECT albumid
FROM albums
WHERE (spanner.search(title_tokens, 'car') OR spanner.search(studio_tokens, 'sun'))
  AND (spanner.search(title_tokens, 'guy') OR spanner.search(studio_tokens, 'electric'))

אפשר להשתמש בשפת rquery או ב-SQL כדי לחפש כמה מונחים באותה עמודה. מומלץ להשתמש ב-rquery כי היא מאפשרת שמירה במטמון של שאילתות פרמטריות בצורה יעילה. מלבד שיעור הפגיעה במטמון של השאילתות, שפות ה-rquery ו-SQL מניבות את אותם שיעורי זמן אחזור וביצועים.

GoogleSQL

SELECT AlbumId
FROM Albums
WHERE SEARCH(Title_Tokens, 'car OR guy')

SELECT AlbumId
FROM Albums
WHERE SEARCH(Title_Tokens, 'car') OR SEARCH(Title_Tokens, 'guy')

PostgreSQL

SELECT albumid
FROM albums
WHERE spanner.search(title_tokens, 'car OR guy')

SELECT albumid
FROM albums
WHERE spanner.search(title_tokens, 'car') OR spanner.search(title_tokens, 'guy')

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

המאמרים הבאים