代碼化

本頁說明如何為表格新增權杖化功能。如要建立搜尋索引中使用的符記,就必須進行符記化。

代碼化是指將值轉換為代碼的程序。您用來將文件權杖化的方法,會決定使用者可對文件執行的搜尋類型和效率。

Spanner 提供自然語言文字、子字串、原文、數字和布林值的分詞器。資料庫結構定義會使用與資料欄所需搜尋類型相符的權杖化工具。權杖化工具具有下列特徵:

  • 每個權杖化工具都是 SQL 函式,可取得輸入內容 (例如字串或數字) 和其他選項的具名引數。
  • 分詞器會輸出 TOKENLIST。

舉例來說,文字字串 The quick brown fox jumps over the lazy dog 會權杖化為 [the,quick,brown,fox,jumps,over,the,lazy,dog]。HTML 字串 The <b>apple</b> is <i>red</i> 會權杖化為 [the,apple,is,red]。

權杖具有下列特性:

  • 權杖會儲存在使用 TOKENLIST 資料類型的資料欄中。
  • 每個符記都會儲存為位元組序列,並可選擇一組相關聯的屬性。舉例來說,在全文應用程式中,符記通常是文字文件中的單一字詞。
  • 將 HTML 值權杖化時,Spanner 會產生屬性,指出權杖在文件中的重要性。Spanner 會使用這些屬性進行評分,提高更醒目字詞 (例如標題) 的排名。

Tokenizer

Spanner 支援下列 tokenizer 函式:

  • 全文分詞器 (TOKENIZE_FULLTEXT) 會為自然語言查詢產生全字詞元。

    範例

    下列兩個函式

    GoogleSQL

    TOKENIZE_FULLTEXT("Yellow apple")
    TOKENIZE_FULLTEXT("Yellow <b>apple</b>", content_type=>"text/html")
    

    PostgreSQL

    本範例使用 spanner.tokenize_fulltext。

    spanner.tokenize_fulltext("Yellow apple")
    spanner.tokenize_fulltext('Yellow <b>apple</b>', context_type=>'text/html')
    

    產生相同的權杖:[yellow,apple]。

  • 子字串權杖化工具 (TOKENIZE_SUBSTRING) 會為每個字詞的每個 N-gram 產生權杖。用於在文字中尋找字詞的子字串。

    範例

    GoogleSQL

    TOKENIZE_SUBSTRING('hello world', ngram_size_min=>4, ngram_size_max=>6)
    

    PostgreSQL

    本範例使用 spanner.tokenize_substring。

    spanner.tokenize_substring('hello world', ngram_size_min=>4, ngram_size_max=>6)
    

    產生下列權杖:[ello,hell,hello,orld,worl,world]。

  • N-gram 符記工具 (TOKENIZE_NGRAMS) 會從輸入內容生成 N-gram,但不會將輸入內容分割成個別字詞。用於加速規則運算式述詞。

    範例

    下列函式:

    GoogleSQL

    TOKENIZE_NGRAMS("Big Time", ngram_size_min=>4, ngram_size_max=>4)
    

    PostgreSQL

    本範例使用 spanner.tokenize_ngrams。

    spanner.tokenize_ngrams('big time', ngram_size_min=>4, ngram_size_max=>4)
    

    產生下列權杖:["Big ","ig T","g Ti"," Tim", "Time"]。

  • 完全比對權杖化工具 (TOKEN 和 TOKENIZE_BOOL) 用於在資料欄中尋找含有特定值的資料列。舉例來說,為產品目錄建立索引的應用程式可能想搜尋特定品牌和顏色的產品。

    範例

    下列函式:

    GoogleSQL

    TOKEN("hello")
    TOKEN(["hello", "world"])
    

    PostgreSQL

    本範例使用 spanner.token。

    spanner.token('hello')
    

    產生下列權杖:[hello]。

    下列函式:

    GoogleSQL

    TOKENIZE_BOOL(true)
    

    PostgreSQL

    本範例使用 spanner.tokenize_bool。

    spanner.tokenize_bool(true)
    

    產生下列權杖:[y]。

  • 數字權杖化工具 (TOKENIZE_NUMBER) 可用來產生一組權杖,加快數字比較搜尋的速度。如果是等號條件,權杖就是數字本身。如果是範圍條件 (例如 rating >= 3.5),權杖組合會更複雜。

    範例

    下列函式陳述式:

    GoogleSQL

    TOKENIZE_NUMBER(42, comparison_type=>'equality')
    TOKENIZE_NUMBER(42, comparison_type=>'all', granularity=>10, min=>1, max=>100)
    

    PostgreSQL

    本範例使用 spanner.tokenize_number。

    spanner.tokenize_number(42, comparison_type=>'equality')
    spanner.tokenize_number(42, comparison_type=>'all', granularity=>10, min=>1, max=>100)
    

    請分別產生下列權杖:"==42" 和 "==42"、"[1,75]"、"[36, 45]"、"[36,55]"、"[36, 75]"。

  • JSON 和 JSONB 權杖化工具 (TOKENIZE_JSON 和 TOKENIZE_JSONB) 可用於產生一組權杖,加速 JSON 相等、包含和索引鍵存在述詞,例如 doc.key = "value" 或 doc[@key] IS NOT NULL (GoogleSQL),以及 doc->'key' = '"value"'::jsonb 或 doc ? 'key' (PostgreSQL)。

權杖化函式通常用於產生的資料欄運算式。這些資料欄定義為 HIDDEN,因此不會包含在 SELECT * 查詢結果中。

以下範例使用全文權杖化工具和數字權杖化工具,建立儲存音樂專輯名稱和評分的資料庫。DDL 陳述式會執行兩項作業:

  1. 定義資料欄 AlbumTitle 和 Rating。
  2. 定義 AlbumTitle_Tokens 和 AlbumRating_Tokens。這些TOKENLIST資料欄會將資料欄中的值權杖化,以便 Spanner 為這些值建立索引。

    GoogleSQL

    CREATE TABLE Albums (
      AlbumId STRING(MAX) NOT NULL,
      AlbumTitle STRING(MAX),
      Rating FLOAT64,
      AlbumTitle_Tokens TOKENLIST AS (TOKENIZE_FULLTEXT(AlbumTitle)) HIDDEN,
      Rating_Tokens TOKENLIST AS (TOKENIZE_NUMBER(Rating)) HIDDEN
    ) PRIMARY KEY(AlbumId);
    

    PostgreSQL

    CREATE TABLE albums (
      albumid character varying NOT NULL,
      albumtitle character varying,
      albumtitle_Tokens spanner.tokenlist GENERATED ALWAYS AS (spanner.tokenize_fulltext(albumtitle)) VIRTUAL HIDDEN,
    PRIMARY KEY(albumid));
    

每當基本值修改時,AlbumTitle_Tokens 和 Rating_Tokens 都會自動更新。

將純文字或 HTML 內容權杖化

文字權杖化支援純文字和 HTML 內容類型。使用 Spanner TOKENIZE_FULLTEXT 函式建立權杖。然後使用 CREATE SEARCH INDEX DDL 陳述式產生搜尋索引。

舉例來說,下列 CREATE TABLE DDL 陳述式會使用 TOKENIZE_FULLTEXT 函式,從 Albums 資料表的 AlbumTitles 建立權杖。CREATE SEARCH INDEX DDL 陳述式會使用新的 AlbumTitles_Tokens 建立搜尋索引。

GoogleSQL

CREATE TABLE Albums (
  AlbumId STRING(MAX) NOT NULL,
  AlbumTitle STRING(MAX),
  AlbumTitle_Tokens TOKENLIST AS (TOKENIZE_FULLTEXT(AlbumTitle)) HIDDEN
) PRIMARY KEY(AlbumId);

CREATE SEARCH INDEX AlbumsIndex ON Albums(AlbumTitle_Tokens)

PostgreSQL

CREATE TABLE albums (
  albumid character varying NOT NULL,
  albumtitle character varying,
  albumtitle_tokens spanner.tokenlist
      GENERATED ALWAYS AS (spanner.tokenize_fulltext(albumtitle)) VIRTUAL HIDDEN,
PRIMARY KEY(albumid));

CREATE SEARCH INDEX albumsindex ON albums(albumtitle_tokens)

權杖化程序會使用下列規則:

  • 權杖化不包括詞幹分析或修正拼寫錯誤的字詞。舉例來說,在「A cat was looking at a group of cats」這類句子中,系統會分別為「cat」和「cats」建立索引。相較於其他搜尋引擎會在寫入時正規化權杖,Spanner 提供擴充搜尋查詢的選項,可納入不同形式的字詞。詳情請參閱「強化查詢模式」。
  • 搜尋索引會包含停用詞 (例如「a」)。
  • 全文搜尋一律不區分大小寫。斷詞程序會將所有權杖轉換為小寫。

詞元化程序會追蹤原始文字中每個詞元的位置。這些位置稍後會用於比對片語。位置會與 docid 一起儲存在搜尋索引中。

Google 會持續改善權杖化演算法。在某些情況下,這可能會導致字串在未來的權杖化方式與現在不同。這種情況應該極為罕見。舉例來說,如果中日韓 (CJK) 語言分詞有所改善,就會發生這種情況。

content_type 引數會指定內容格式是否使用純文字或 HTML。請使用下列設定來設定 content_type:

  • 如要進行文字權杖化,請將 content_type 引數設為「text/plain」。這是預設設定。
  • 如要進行 HTML 斷詞,請將 content_type 引數設為 "text/html"。 如果沒有這個引數,系統會將 HTML 代碼視為標點符號。在 HTML 模式下,Spanner 會使用經驗法則推論文字在網頁上的醒目程度。例如文字是否位於標題中,或是字型大小。 HTML 支援的屬性包括 small、medium、large、title 和「link」。與位置一樣,屬性會與權杖一起儲存在搜尋索引中。權杖化不會為任何 HTML 標記建立權杖。

權杖屬性不會影響比對作業,也不會影響 SEARCH 或 SEARCH_SUBSTRING 函式的結果。這些信號只會用於排名。

以下範例說明如何將文字權杖化:

GoogleSQL

CREATE TABLE T (
  ...
  Text STRING(MAX),
  Html STRING(MAX),
  Text_Tokens TOKENLIST
    AS (TOKENIZE_FULLTEXT(Text, content_type=>"text/plain")) HIDDEN,
  Html_Tokens TOKENLIST
    AS (TOKENIZE_FULLTEXT(Html, content_type=>"text/html")) HIDDEN
) PRIMARY KEY(...);

PostgreSQL

CREATE TABLE t (
  ...
  text character varying,
  html character varying,
  text_tokens spanner.tokenlist
      GENERATED ALWAYS AS (spanner.tokenize_fulltext(text, content_type=>"text/plain")) VIRTUAL HIDDEN,
  html_tokens spanner.tokenlist
      GENERATED ALWAYS AS (spanner.tokenize_fulltext(html, content_type=>'type/html')) VIRTUAL HIDDEN,
PRIMARY KEY(...));

使用 language_tag 引數精確偵測語言

根據預設,權杖化功能會自動偵測輸入語言。如果已知輸入語言,可以使用 language_tag 引數調整這項行為:

GoogleSQL

AlbumTitle_Tokens TOKENLIST
  AS (TOKENIZE_FULLTEXT(AlbumTitle, language_tag=>"en-us")) HIDDEN

PostgreSQL

albumtitle_tokens spanner.tokenlist
      GENERATED ALWAYS AS (spanner.tokenize_fulltext(albumtitle, language_tag=>'en-us')) VIRTUAL HIDDEN

大多數應用程式都不會指定 language_tag 引數,而是依賴自動偵測語言功能。如要對中文、韓文和日文等亞洲語言進行區隔,不需要設定權杖化語言。

以下範例說明 language_tag 如何影響權杖化:

權杖化函式 產生的權杖
TOKENIZE_FULLTEXT("A tout pourquoi il y a un parce que") [a, tout, pourquoi, il, ya, un, parce, que]
TOKENIZE_FULLTEXT("A tout pourquoi il y a un parce que", \ language_tag=>"fr") [a, tout, pourquoi, il, y, a, un, parce, que]
TOKENIZE_FULLTEXT("旅 行") 兩個權杖:[旅, 行]
TOKENIZE_FULLTEXT("旅 行", language_tag=>"zh") 一個詞元:[旅行]

後續步驟