本頁說明如何為表格新增權杖化功能。如要建立搜尋索引中使用的符記,就必須進行符記化。
代碼化是指將值轉換為代碼的程序。您用來將文件權杖化的方法,會決定使用者可對文件執行的搜尋類型和效率。
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 陳述式會執行兩項作業:
- 定義資料欄
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") |
一個詞元:[旅行] |