內建的 MySQL 全文剖析器使用單字之間的空白作為分隔符號,以決定單字的開始和結束位置,這在使用不使用單字分隔符號的表意語言時會是一個限制。為了處理此限制,MySQL 提供了支援中文、日文和韓文 (CJK) 的 ngram 全文剖析器。ngram 全文剖析器支援與 InnoDB
和 MyISAM
搭配使用。
MySQL 也為日文提供了 MeCab 全文剖析器外掛程式,可將文件標記化為有意義的單字。如需詳細資訊,請參閱第 14.9.9 節,「MeCab 全文剖析器外掛程式」。
ngram 是來自給定文字序列的 n
個字元的連續序列。ngram 剖析器將文字序列標記化為 n
個字元的連續序列。例如,您可以使用 ngram 全文剖析器針對 n
的不同值來標記化「“abcd”」。
n=1: 'a', 'b', 'c', 'd'
n=2: 'ab', 'bc', 'cd'
n=3: 'abc', 'bcd'
n=4: 'abcd'
ngram 全文剖析器是內建的伺服器外掛程式。與其他內建的伺服器外掛程式一樣,它會在伺服器啟動時自動載入。
第 14.9 節,「全文搜尋函式」中描述的全文搜尋語法適用於 ngram 剖析器外掛程式。此章節將說明剖析行為的差異。全文相關的組態選項,除了最小和最大單字長度選項(innodb_ft_min_token_size
、innodb_ft_max_token_size
、ft_min_word_len
、ft_max_word_len
)之外,也適用。
設定 ngram 權杖大小
ngram 剖析器的預設 ngram 權杖大小為 2(雙字母組)。例如,若權杖大小為 2,則 ngram 剖析器會將字串「“abc def”」剖析為四個權杖:「“ab”」、「“bc”」、「“de”」和「“ef”」。
ngram 權杖大小可使用 ngram_token_size
組態選項進行設定,其最小值為 1,最大值為 10。
通常,ngram_token_size
會設定為您要搜尋的最大權杖大小。如果您只想搜尋單個字元,請將 ngram_token_size
設定為 1。較小的權杖大小會產生較小的全文搜尋索引,並加快搜尋速度。如果您需要搜尋由多個字元組成的單字,請據此設定 ngram_token_size
。例如,「“Happy Birthday”」在簡體中文中是「“生日快乐”」,其中「“生日”」是「“birthday”」,而「“快乐”」翻譯為「“happy”」。若要搜尋這類兩個字元的單字,請將 ngram_token_size
設定為 2 或更高的值。
作為唯讀變數,ngram_token_size
只能設定為啟動字串的一部分,或設定在組態檔中
啟動字串
mysqld --ngram_token_size=2
組態檔
[mysqld] ngram_token_size=2
針對使用 ngram 剖析器的 FULLTEXT
索引,會忽略下列最小和最大單字長度組態選項:innodb_ft_min_token_size
、innodb_ft_max_token_size
、ft_min_word_len
和 ft_max_word_len
。
建立使用 ngram 剖析器的 FULLTEXT 索引
若要建立使用 ngram 剖析器的 FULLTEXT
索引,請使用 CREATE TABLE
、ALTER TABLE
或 CREATE INDEX
指定 WITH PARSER ngram
。
以下範例示範如何建立具有 ngram
FULLTEXT
索引的表格、插入範例資料(簡體中文文字),以及在 Information Schema 的 INNODB_FT_INDEX_CACHE
表格中檢視 Token 化後的資料。
mysql> USE test;
mysql> CREATE TABLE articles (
id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
title VARCHAR(200),
body TEXT,
FULLTEXT (title,body) WITH PARSER ngram
) ENGINE=InnoDB CHARACTER SET utf8mb4;
mysql> SET NAMES utf8mb4;
INSERT INTO articles (title,body) VALUES
('数据库管理','在本教程中我将向你展示如何管理数据库'),
('数据库应用开发','学习开发数据库应用程序');
mysql> SET GLOBAL innodb_ft_aux_table="test/articles";
mysql> SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_INDEX_CACHE ORDER BY doc_id, position;
若要將 FULLTEXT
索引新增至現有表格,您可以使用 ALTER TABLE
或 CREATE INDEX
。例如
CREATE TABLE articles (
id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
title VARCHAR(200),
body TEXT
) ENGINE=InnoDB CHARACTER SET utf8mb4;
ALTER TABLE articles ADD FULLTEXT INDEX ft_index (title,body) WITH PARSER ngram;
# Or:
CREATE FULLTEXT INDEX ft_index ON articles (title,body) WITH PARSER ngram;
ngram 剖析器空格處理
ngram 剖析器在剖析時會消除空格。例如
「ab cd」會被剖析為 「ab」、「cd」
「a bc」會被剖析為 「bc」
ngram 剖析器停用字處理
內建的 MySQL 全文剖析器會將單字與停用字清單中的項目進行比較。如果單字等於停用字清單中的項目,該單字就會從索引中排除。對於 ngram 剖析器,停用字處理方式有所不同。ngram 剖析器不會排除與停用字清單中的項目相等的 Token,而是排除包含停用字的 Token。例如,假設 ngram_token_size=2
,包含 「a,b」 的文件會被剖析為 「a,」 和 「,b」。如果逗號 (「,」) 被定義為停用字,則 「a,」 和 「,b」 都會從索引中排除,因為它們都包含逗號。
預設情況下,ngram 剖析器使用預設的停用字清單,其中包含英文停用字清單。若要使用適用於中文、日文或韓文的停用字清單,您必須建立自己的清單。如需建立停用字清單的相關資訊,請參閱第 14.9.4 節〈全文停用字〉。
長度大於 ngram_token_size
的停用字會被忽略。
ngram 剖析器詞彙搜尋
對於自然語言模式搜尋,搜尋詞彙會轉換為 ngram 詞彙的聯集。例如,字串 「abc」(假設 ngram_token_size=2
)會轉換為 「ab bc」。假設有兩份文件,一份包含 「ab」,另一份包含 「abc」,則搜尋詞彙 「ab bc」 會比對到這兩份文件。
對於布林模式搜尋,搜尋詞彙會轉換為 ngram 片語搜尋。例如,字串 'abc'(假設 ngram_token_size=2
)會轉換為 '「ab bc」'。假設有兩份文件,一份包含 'ab',另一份包含 'abc',則搜尋片語 '「ab bc」' 只會比對到包含 'abc' 的文件。
ngram 剖析器萬用字元搜尋
由於 ngram FULLTEXT
索引只包含 ngram,不包含詞彙開頭的相關資訊,因此萬用字元搜尋可能會傳回非預期的結果。下列行為適用於使用 ngram FULLTEXT
搜尋索引的萬用字元搜尋
如果萬用字元搜尋的前綴詞彙短於 ngram Token 大小,查詢會傳回所有包含以該前綴詞彙開頭的 ngram Token 的索引列。例如,假設
ngram_token_size=2
,搜尋 「a*」 會傳回所有以 「a」 開頭的資料列。如果萬用字元搜尋的前綴詞彙長於 ngram Token 大小,則前綴詞彙會轉換為 ngram 片語,並且忽略萬用字元運算子。例如,假設
ngram_token_size=2
,「abc*」 萬用字元搜尋會轉換為 「ab bc」。
ngram 剖析器片語搜尋
片語搜尋會轉換為 ngram 片語搜尋。例如,搜尋片語 「abc」 會轉換為 「ab bc」,這會傳回包含 「abc」 和 「ab bc」 的文件。
搜尋片語 「abc def」 會轉換為 「ab bc de ef」,這會傳回包含 「abc def」 和 「ab bc de ef」 的文件。不傳回包含 「abcdef」 的文件。