前言
最近在学习和了解 MySQL 8 自带的全文搜索功能。自己在看资料的时候顺便翻译了一下,希望对大家有用。(章节序号可能有所差异,因为官方文档会不定期更新)
官方原文链接如下:《ngram Full-Text Parser》
内置的 MySQL 全文解析器使用单词之间的空格作为分隔符来确定单词的开始和结束位置,这在使用不使用单词分隔符的表意语言时是一个限制。为了解决此限制,MySQL 提供了一个支持中文、日文和韩文 (CJK) 的 ngram 全文解析器。InnoDB 和 MyISAM 存储引擎的表都可以使用 ngram 全文解析器。
注意
MySQL 还为日语提供了一个 MeCab 全文解析器插件,该插件将文档标记成有意义的单词。更多信息,参阅 《12.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 全文解析器是一个内置的服务器插件。与其他内置服务器插件一样,它会在服务器启动时自动加载。
在 《12.9 全文搜索功能》 描述的全文搜索语法适用于 ngram 解析器插件。与全文相关的配置选项(最小和最大字长选项(innodb_ft_min_token_size、innodb_ft_max_token_size、ft_min_word_len、ft_max_word_len)也适用。
配置 ngram 字长大小
ngram 解析器的默认 ngram 字长大小为 2 (bigram)。例如,当字长大小为 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 表 的标记化数据。
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; # 或者: 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 解析器使用默认的停用字列表,其中包含英语停用字列表。对于适用于中文、日文或韩文的停用字列表,您必须创建自己的停用字列表。有关创建停用字列表的信息,参阅 《12.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”的文档。