12.9.8 ngram 全文分析器

内置的 MySQL 全文语法分析器使用单词之间的空白作为定界符来确定单词的开始和结尾,这在使用不使用单词定界符的 table 意语言时是一个限制。为了解决此限制,MySQL 提供了一个支持中文,日文和韩文(CJK)的 ngram 全文分析器。 ngram 全文分析器支持与InnoDBMyISAM一起使用。

Note

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_sizeinnodb_ft_max_token_sizeft_min_word_lenft_max_word_len)外,与全文相关的配置选项也适用。

配置 ngram 令牌大小

ngram 解析器的默认 ngram 令牌大小为 2(bigram)。例如,令牌大小为 2 时,ngram 解析器将字符串“ abc def”解析为四个令牌:“ ab”,“ bc”,“ de”和“ ef”。

可以使用ngram_token_size配置选项来配置 ngram 令牌大小,该选项的最小值为 1,最大值为 10.

通常,将ngram_token_size设置为要搜索的最大令牌的大小。如果只打算搜索单个字符,请将ngram_token_size设置为 1.较小的令牌大小将产生较小的全文本搜索索引,并加快搜索速度。如果您要搜索包含多个字符的单词,请相应地设置ngram_token_size。例如,“生日快乐”在简体中文中是“生日快乐”,其中“生日”是“生日”,“快乐”翻译为“快乐”。要搜索诸如此类的两个字符的单词,请将ngram_token_size设置为 2 或更高的值。

ngram_token_size作为只读变量,只能设置为启动字符串的一部分或在配置文件中:

  • Startup string:
mysqld --ngram_token_size=2
  • Configuration file:
[mysqld]
ngram_token_size=2

Note

对于使用 ngram 解析器的FULLTEXT索引,将忽略以下最小和最大字长配置选项:innodb_ft_min_token_sizeinnodb_ft_max_token_sizeft_min_word_lenft_max_word_len

创建使用 ngram 解析器的 FULLTEXT 索引

要创建使用 ngram 解析器的FULLTEXT索引,请使用CREATE TABLEALTER TABLECREATE INDEX指定WITH PARSER ngram

下面的示例演示如何创建一个具有ngram FULLTEXT索引的 table,插入示例数据(简体中文文本)以及在INFORMATION_SCHEMA.INNODB_FT_INDEX_CACHEtable 中查看标记化数据。

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
    ('数据库 Management','在本教程中我将向你展示如何 Management 数据库'),
    ('数据库应用开发','学习开发数据库应用程序');

mysql> SET GLOBAL innodb_ft_aux_table="test/articles";

mysql> SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_INDEX_CACHE ORDER BY doc_id, position;

要将FULLTEXT索引添加到现有 table 中,可以使用ALTER TABLECREATE INDEX。例如:

CREATE TABLE articles (
      id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
      title VARCHAR(200),
      body TEXT
     ) ENGINE=InnoDB CHARACTER SET utf8;

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 全文分析器将单词与停用词列 table 中的条目进行比较。如果单词等于停用词列 table 中的条目,则该单词将从索引中排除。对于 ngram 解析器,停用词处理的执行方式有所不同。 ngram 解析器不排除与停用词列 table 中的条目相等的令牌,而是排除“包含”停用词的令牌。例如,假设ngram_token_size=2,则将包含“ a,b”的文档解析为“ a,”和“,b”。如果将逗号(“,”)定义为停用词,则“ a”和“,b”都将从索引中排除,因为它们都包含逗号。

默认情况下,ngram 解析器使用默认停用词列 table,其中包含英语停用词列 table。对于适用于中文,日语或韩语的停用词列 table,您必须创建自己的停用词。有关创建停用词列 table 的信息,请参见第 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”的文档。