14.9.8 ngram 全文解析器
MySQL 的内置全文解析器使用空格来确定单词的开始和结束位置,这对处理不使用单词 delimiter 的ideographic语言是一种限制。为了解决这个限制,MySQL 提供了 ngram 全文解析器,它支持中文、日语和韩语(CJK)。ngram 全文解析器可以与InnoDB
和MyISAM
一起使用。
MySQL 还提供了 MeCab 全文解析器插件用于日语,它将文档 tokenize 成有意义的单词。更多信息请见第14.9.9节,“MeCab全文解析器插件”。
ngram 是指从给定的文本序列中连续出现的n
个字符的序列。ngram 解析器将文本序列 tokenize 成连续出现的n
个字符。例如,您可以使用 ngram 全文解析器对“abcd”进行 tokenization,以不同的n
值。
Press CTRL+C to copyn=1: 'a', 'b', 'c', 'd' n=2: 'ab', 'bc', 'cd' n=3: 'abc', 'bcd' n=4: 'abcd'
ngram 全文解析器是一个内置的服务器插件。与其他内置服务器插件一样,它将在服务器启动时自动加载。
全文搜索语法,见第14.9节,“Full-Text Search Functions”。该部分描述了ngram解析器插件的解析行为差异。除了最小和最大词长选项(innodb_ft_min_token_size
、innodb_ft_max_token_size
、ft_min_word_len
、ft_max_word_len
)之外的全文相关配置选项也适用。
ngram解析器的默认ngram令牌大小为2(bigram)。例如,令牌大小为2时,ngram解析器将字符串“abc def”分解成四个令牌:“ab”、“bc”、“de”和“ef”。
ngram令牌大小可以使用ngram_token_size
配置选项进行配置,该选项的最小值为1,最大值为10。
通常,ngram_token_size
设置为您想要搜索的最大 token 大小。如果您只想搜索单个字符,请将ngram_token_size
设置为1。较小的 token 大小将生成较小的全文搜索索引,并且搜索速度更快。如果您需要搜索由多个字符组成的词语,请相应地设置ngram_token_size
。例如,“生日快乐”在简体中文中是“生日birthday快乐happy”,要搜索两个字符的词语,如这些,请将ngram_token_size
设置为2或更高。
作为只读变量,ngram_token_size
只能在启动字符串中或配置文件中设置:
-
启动字符串:
Press CTRL+C to copymysqld --ngram_token_size=2
-
配置文件:
Press CTRL+C to copy[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
索引,指定CREATE TABLE
、ALTER TABLE
或CREATE INDEX
语句中:WITH PARSER ngram
。
以下示例演示了创建带有ngramFULLTEXT
索引的表、插入样本数据(简体中文文本)和在信息_schemaINNODB_FT_INDEX_CACHE
表中查看tokenized数据。
Press CTRL+C to copymysql> 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
。例如:
Press CTRL+C to copyCREATE 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解析器在解析时会删除空格。例如:
-
“ab cd”将被解析为“ab”,“cd”
-
“a bc”将被解析为“bc”
MySQL的内置全文搜索解析器将单词与停用词列表中的条目进行比较。如果单词等于停用词列表中的某个条目,该单词将被排除在索引中。对于ngram解析器,停用词处理方式不同。相反,它们会排除包含停用词的令牌。例如,假设ngram_token_size=2
,包含“a,b”的文档将被解析为“a,”和“,b”。如果逗号(“,”)被定义为停用词,那么“a,”和“,b”都将被排除在索引中,因为它们包含逗号。
默认情况下,ngram 解析器使用默认的停用词列表,该列表包含英语停用词。对于适用于中文、日语或韩文的停用词列表,您需要创建自己的。有关创建停用词列表的信息,请见第14.9.4节,“全文停用词”。
长度大于ngram_ token_size
的停用词将被忽略。
在自然语言模式搜索中,搜索术语将转换为 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 FULLTEXT
索引只包含ngrams,而不包含术语的开始信息,通配符搜索可能返回意外结果。以下行为适用于使用ngram FULLTEXT
搜索索引的通配符搜索:
-
如果通配符搜索的前缀词短于ngram token size,查询将返回所有包含以该前缀词开头的ngram tokens的索引行。例如,假设
ngram_token_size=2
,搜索“a*”将返回所有以“a”开头的行。 -
如果通配符搜索的前缀词长于ngram token size,前缀词将被转换为ngram短语,并忽略通配符操作符。例如,假设
ngram_token_size=2
,通配符搜索“abc*”将被转换为“ab bc”。
短语搜索将被转换为ngram短语搜索。例如,搜索短语“abc”将被转换为“ab bc”“abc”和“ab bc”的文档。
搜索短语“abc def”被转换为“ab bc de ef”“abc def”和“ab bc de ef”的文档。包含“abcdef”的文档不被返回。