搜尋查詢擴充

本頁說明如何使用查詢強化功能,進行全文搜尋

為提高找到相關結果的關聯性,Spanner 提供進階功能,可擴充搜尋查詢,納入相關字詞、同義詞和拼字修正。Spanner 提供下列查詢強化選項:

強化查詢

如要使用強化查詢,請在 SEARCH 函式中設定 enhance_query=>true。Spanner 接著會自動擴大搜尋查詢範圍,納入相關字詞和同義字、套用詞幹,以及修正拼字。舉例來說,使用強化查詢時,搜尋查詢 hotl cal 會比對到專輯 Hotel California

GoogleSQL

SELECT AlbumId
FROM Albums
WHERE SEARCH(AlbumTitle_Tokens, 'hotl cal', enhance_query=>true)

PostgreSQL

SELECT albumid
FROM albums
WHERE spanner.search(albumtitle_tokens, 'hotl cal', enhance_query=>true)

enhance_query 是查詢時間選項,不會影響權杖化。 無論是否使用 enhance_query,您都可以使用相同的搜尋索引。

Google 會持續改善查詢強化演算法,因此,含有 enhance_query => true 的查詢可能會隨著時間推移,產生略有不同的結果。

使用 enhance_query 時,由於擴展搜尋查詢和執行產生的較大查詢會造成額外負擔,因此可能會增加延遲。

自訂字典

您可以在 Spanner 全文搜尋中使用自訂字典,為資料集中的字詞定義同義詞。這項功能有助於擷取同義字、縮寫、同義詞和其他字詞變化,進而改善搜尋結果的檢索作業。

建立自訂字典表

自訂字典是由使用者建立的表格,內含字詞和同義詞的鍵/值組合。如要建立一個,請在 CREATE TABLE 陳述式中加入 fulltext_dictionary_table = true 選項。資料表必須包含以下兩欄:

  • Key:不可為空值的字串資料欄,用於擴展同義字。
  • Value:不可為空值的字串陣列資料欄,代表鍵的同義字陣列。

表格中只能有 KeyValue 欄。 如果搜尋字詞與字典中的 Key 相符,搜尋範圍會擴大,納入 Value 中的所有對應同義字和主要字詞。 以下範例會建立名為 MyCustomDictionary 的自訂字典資料表。建立這個資料表時,您也必須設定資料表選項 fulltext_dictionary_table=true

GoogleSQL

CREATE TABLE MyCustomDictionary (
  Key STRING(MAX) NOT NULL,
  Value ARRAY<STRING(MAX)> NOT NULL,
) PRIMARY KEY(Key),
OPTIONS (fulltext_dictionary_table = true);

PostgreSQL

CREATE TABLE mycustomdictionary (
  key character varying  NOT NULL,
  value character varying [] NOT NULL,
  PRIMARY KEY(key)
)  WITH ( type = 'fulltext_dictionary')

建立資料表後,請插入同義字:

GoogleSQL

INSERT INTO MyCustomDictionary (Key, Value) VALUES
('album', ['vinyl', 'cassette']),
('edm', ['electronic dance music']);

PostgreSQL

INSERT INTO mycustomdictionary (key, value) VALUES
('album', ARRAY['vinyl', 'cassette']),
('edm', ARRAY['electronic dance music']);

填寫表格時,請注意下列事項:

  • 索引鍵必須是單一字詞。
  • 值可以是單一字詞,或多個字詞組成的詞組。如果值包含多個字詞,系統會在查詢擴充期間將其視為詞組搜尋。
  • 所有鍵和值都應為小寫字母。這樣一來,這些字詞就會與搜尋權杖相符,而預設權杖化工具會將搜尋權杖轉換為小寫。

只有在搜尋字詞與 Key 相符時,系統才會擴大搜尋範圍。如果搜尋字詞與 Value 中的同義詞相符,但與 Key 不符,搜尋範圍就不會擴大。如果您需要雙向對應 (例如,搜尋 vinylcassette 時也能找到 album),也必須在字典表格中插入反向對應。以下範例說明如何插入 albumvinylcassette 的雙向對應:

GoogleSQL

INSERT INTO MyCustomDictionary (Key, Value)
-- 1. Insert album -> vinyl, cassette
SELECT 'album', ['vinyl', 'cassette']
UNION ALL
-- 2. Insert vinyl -> album and cassette -> album
SELECT syn, ['album']
FROM UNNEST(['vinyl', 'cassette']) AS syn;

PostgreSQL

INSERT INTO mycustomdictionary (key, value)
-- 1. Insert album -> vinyl, cassette
SELECT 'album', ARRAY['vinyl', 'cassette']
UNION ALL
-- 2. Insert vinyl -> album and cassette -> album
SELECT syn, ARRAY['album']
FROM unnest(ARRAY['vinyl', 'cassette']) AS syn;

在搜尋查詢中使用自訂字典

如要使用自訂字典,請在 SEARCH 函式的 dictionary 引數中指定字典資料表名稱。

  • 如果搜尋字詞是字典中的鍵,SEARCH 也會尋找其值。字詞 album 會比對含有 vinylcassette 的郵件。

    GoogleSQL

    SELECT MessageId, Body
    FROM Messages
    WHERE SEARCH(Body_Tokens, 'album', dictionary=>'MyCustomDictionary');
    

    PostgreSQL

    SELECT messageid, body
    FROM messages
    WHERE spanner.search(body_tokens, 'album', dictionary=>'mycustomdictionary');
    
  • 如果字典值包含多個字詞 (例如鍵 edmelectronic dance music),系統會將其視為詞組搜尋。也就是說,系統會將完全比對的關鍵字視為比對條件,因此搜尋字詞必須與關鍵字完全相同,且順序一致。舉例來說,下列查詢會傳回包含「電子舞曲」這個確切詞組的結果,但不會比對「舞曲電子音樂」。這項功能主要用於擴充縮寫,使用方式如下:

    GoogleSQL

    SELECT MessageId, Body
    FROM Messages
    WHERE SEARCH(Body_Tokens, 'edm', dictionary=>'MyCustomDictionary');
    

    PostgreSQL

    SELECT messageid, body
    FROM messages
    WHERE spanner.search(body_tokens, 'edm', dictionary=>'mycustomdictionary');
    

字典查詢過時

根據預設,自訂字典項目的讀取時間最多會延遲 15 秒。因為讀取有些過時的資料,比讀取最新資料更有效率,因此可減少讀取作業的負擔。因此,字典條目的變更最多可能需要 15 秒,才會反映在搜尋查詢中。您可以透過下列方式覆寫這個行為:

  • 使用 fulltext_dictionary_staleness 表格選項。
  • 使用 fulltext_dictionary_staleness 查詢提示,進行更精細的控制。

如果同時使用查詢提示和資料表選項,查詢提示會覆寫資料表選項。

fulltext_dictionary_staleness資料表選項

您可以為字典資料表設定 fulltext_dictionary_staleness 選項。除非查詢提示覆寫此值,否則使用這個字典資料表的所有查詢都會使用這個過時值。

GoogleSQL

以下範例說明如何使用 fulltext_dictionary_staleness 選項 CREATE 資料表:

CREATE TABLE MyCustomDictionary (
  Key STRING(MAX) NOT NULL,
  Value ARRAY<STRING(MAX)> NOT NULL,
) PRIMARY KEY(Key),
OPTIONS (
  fulltext_dictionary_table = true,
  fulltext_dictionary_staleness = '5s'
);

以下範例說明如何使用 ALTER 表格變更或設定 fulltext_dictionary_staleness 選項:

ALTER TABLE MyCustomDictionary SET OPTIONS (
  fulltext_dictionary_staleness = '60s'
);

PostgreSQL

以下範例說明如何使用 fulltext_dictionary_staleness 選項 CREATE 資料表:

-- Create with 5s staleness
CREATE TABLE mycustomdictionary (
  key character varying NOT NULL,
  value character varying[]  NOT NULL,
  PRIMARY KEY(key)
) WITH (
  type = 'fulltext_dictionary',
  fulltext_dictionary_staleness = '5s'
);

PostgreSQL 介面不支援 ALTER 資料表,無法變更或設定 fulltext_dictionary_staleness 選項。

fulltext_dictionary_staleness 查詢提示

如要更精細地控管,可以使用 fulltext_dictionary_staleness 查詢提示,為個別查詢指定不同的陳舊程度。這項提示會覆寫表格層級的設定。

以下範例使用提示,以零過時程度執行字典表格查詢。確保系統讀取的是最新字典條目。這種做法可能會增加查詢延遲時間,因為相較於允許資料過時,讀取最新資料的效率較低。

GoogleSQL

@{fulltext_dictionary_staleness="0s"}
SELECT MessageId, Body
FROM Messages
WHERE SEARCH(Body_Tokens, 'Bill', dictionary=>'MyCustomDictionary');

PostgreSQL

/*@ fulltext_dictionary_staleness='0s' */
SELECT messageid, body
FROM messages
WHERE spanner.search(body_tokens, 'Bill', dictionary=>'mycustomdictionary');

自訂字典資料表的已知限制

  • 使用自訂字典表時,Spanner 匯入和匯出功能僅提供有限支援。
  • 自訂字典資料表必須在預設結構定義中建立,無法在已命名的結構定義中建立。
  • 自訂字典資料表僅支援預設的 SEARCH 查詢方言

搭配使用自訂字典與進階查詢

您可以在 SEARCH 函式中同時設定 dictionaryenhance_query=>true,將自訂字典同義字與 enhanced query 結合。查詢擴充功能可使用常見同義詞或拼字修正來擴充查詢,而自訂字典則可讓您自行定義擴充內容。舉例來說,如果 enhance_queryalbum 擴展為包含 record,且 MyCustomDictionaryalbum 對應至 ['vinyl', 'cassette'],則下列查詢會比對包含 albumrecordvinylcassette 的訊息:

GoogleSQL

SELECT MessageId, Body
FROM Messages
WHERE SEARCH(Body_Tokens, 'album', enhance_query=>true, dictionary=>'MyCustomDictionary');

PostgreSQL

SELECT messageid, body
FROM messages
WHERE spanner.search(body_tokens, 'album', enhance_query=>true, dictionary=>'mycustomdictionary');

如果同時啟用這兩項強化功能,系統會分別對原始搜尋字詞進行強化,且一項強化功能產生的字詞不會做為另一項功能的輸入內容。

後續步驟