代碼化

本頁說明如何為資料表新增權杖化功能。建立搜尋索引時,必須先進行權杖化,才能建立權杖。

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

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 會使用這些屬性進行評分,以提升更顯眼的字詞 (例如標題)。

分詞器

Spanner 支援下列權杖化函式:

  • 全文權杖化工具 (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 元語法產生符記。用於在文字中尋找字詞的子字串。

    示例

    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 元語法權杖化工具 (TOKENIZE_NGRAMS):從輸入內容產生 n 元語法 (不會將輸入內容分割成個別字詞)。用於加速規則運算式述詞。

    示例

    下列函式:

    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"]

  • 完全相符的權杖化工具 (TOKENTOKENIZE_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_JSONTOKENIZE_JSONB) 用於產生一組權杖,可加速 JSON 包含和鍵存在性述詞,例如 doc[@key] IS NOT NULL (GoogleSQL) 或 doc ? 'key' (PostgreSQL)。

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

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

  1. 定義資料欄 AlbumTitleRating
  2. 定義 AlbumTitle_TokensAlbumRating_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_TokensRating_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 支援的屬性包括 smallmediumlargetitle 和 `link'。與位置相同,這個屬性會與搜尋索引中的權杖一起儲存。權杖化程序不會為任何 HTML 標記建立權杖。

權杖屬性不會影響比對作業,也不會影響 SEARCHSEARCH_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") 一個權杖:「旅行」

後續步驟