本頁說明如何為資料表新增權杖化功能。建立搜尋索引時,必須先進行權杖化,才能建立權杖。
代碼化是將值轉換為代碼的過程。您用來將文件權杖化的方法,會決定使用者可對文件執行的搜尋類型和效率。
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"]
。完全相符的權杖化工具 (
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] IS NOT NULL
(GoogleSQL) 或doc ? 'key'
(PostgreSQL)。
權杖化函式通常用於產生的資料欄運算式。這些資料欄定義為 HIDDEN
,因此不會納入 SELECT *
查詢結果。
以下範例會使用全文檢索權杖化工具和數字權杖化工具,建立儲存音樂專輯名稱和評分的資料庫。DDL 陳述式會執行以下兩項作業:
- 定義資料欄
AlbumTitle
和Rating
。 定義
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") |
一個權杖:「旅行」 |