在搜尋索引中搜尋多個欄

搜尋索引可為多個符號化欄位建立索引,讓這些欄位的查詢更有效率。本頁面說明如何針對多個資料欄執行搜尋作業,這是一種全文搜尋

搜尋索引的結構可確保查詢不需要分散式彙整,進而確保查詢的效能可預測。由於所有符記都會在相同的分割區中與基本資料表資料列對應,因此可避免分散的彙整作業。

舉例來說,請參考下列結構定義:

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_TokensStudio_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 不含「car」一詞的所有文件。

    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。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')

您也可以在同一個查詢中使用全文搜尋函式,搭配搜尋索引加速處理非文字條件。

後續步驟