内置的 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_token_size
配置选项配置 ngram 标记大小,该选项的最小值为 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
索引的表、插入示例数据(简体中文文本)以及在信息模式 INNODB_FT_INDEX_CACHE
表中查看标记化数据。
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 解析器不会排除与停用词列表中的条目相同的词,而是排除包含停用词的词。例如,假设 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 词大小,则查询将返回包含以前缀词开头的 ngram 词的所有索引行。例如,假设
ngram_token_size=2
,则对 “a*” 的搜索将返回以 “a” 开头的所有行。如果通配符搜索的前缀词长于 ngram 词大小,则前缀词将被转换为 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” 的文档将不会被返回。