求知 文章 文库 Lib 视频 iPerson 课程 认证 咨询 工具 讲座 Model Center   Code  
会员   
要资料
 
 

mysql教程
MySQL快速学习入门
MySQL是什么
MySQL安装
MySQL示例数据库
MySQL导入示例数据库
MySQL基础教程
MySQL查询数据
MySQL WHERE语句
MySQL插入数据
MySQL更新表数据
MySQL删除表数据
MySQL创建与删除数据库
MySQL创建表
MySQL修改表结构
MySQL重命名表
MySQL数据类型
高级部分
MySQL技巧
MySQL存储过程
MySQL视图
MySQL触发器
MySQL管理
MySQL全文搜索
MySQL函数
应用程序连接
MySQL+Node.js连接和操作
Python+MySQL连接和操作
 
 

MySQL ngram全文解析器
529 次浏览
4次  

本教程将向您展示如何使用MySQL ngram全文解析器来支持中文,日文,韩文等表意语言的全文搜索。

MySQL ngram全文解析器简介

MySQL内置的全文解析器使用空格确定单词的开始和结束。当涉及汉语,日语或韩语等表意语言语言时,这是一个限制,因为这些语言不使用分词符。

为了解决这个问题,MySQL提供了ngram全文解析器。自MySQL5.7.6版起,MySQL将ngram全文解析器作为内置的服务器插件,这意味着当MySQL数据库服务器启动时,MySQL会自动加载该插件。 MySQL支持用于InnoDB和MyISAM存储引擎的ngram全文解析器。

根据定义,ngram是来自文本序列的多个字符的连续序列。 ngram全文解析器的主要功能是将文本序列标记为n个字符的连续序列。

以下说明了ngram全文解析器如何标记不同值n的文本序列:

n = 1: 'm','y','s','q','l'
n = 2: 'my', 'ys', 'sq','ql'
n = 3: 'mys', 'ysq', 'sql'
n = 4: 'mysq', 'ysql'
n = 5: 'mysql'

使用 ngram 解析器创建FULLTEXT索引

要创建使用ngram全文解析器的FULLTEXT索引,可以在CREATE TABLE,ALTER TABLE或CREATE INDEX语句中添加WITH PARSER ngram。

例如,以下语句创建新的帖子表,并将标题和正文列添加到使用ngram全文解析器的FULLTEXT索引。

USE testdb;
CREATE TABLE posts (
id INT PRIMARY KEY AUTO_INCREMENT,
title VARCHAR(255),
body TEXT,
FULLTEXT ( title , body ) WITH PARSER NGRAM
) ENGINE=INNODB CHARACTER SET UTF8;

以下INSERT语句赂posts表中插入一个新行:

SET NAMES utf8;

INSERT INTO posts(title,body)
VALUES('MySQL全文搜索','MySQL提供了具有许多好的功能的内置全文搜索'),
('MySQL教程','学习MySQL快速,简单和有趣');

请注意,SET NAMES语句设置客户端和服务器将用于发送和接收数据的字符集; 在本示例中,它使用的是utf8。

要查看ngram如何标记文本,请使用以下语句:

SET GLOBAL innodb_ft_aux_table="testdb/posts";

SELECT
*
FROM
information_schema.innodb_ft_index_cache
ORDER BY doc_id , position;

执行上面查询语句,得到以下结果 -

mysql> SELECT
*
FROM
information_schema.innodb_ft_index_cache
ORDER BY doc_id , position;
+------+--------------+-------------+-----------+--------+----------+
| WORD | FIRST_DOC_ID | LAST_DOC_ID | DOC_COUNT | DOC_ID | POSITION |
+------+--------------+-------------+-----------+--------+----------+
| my | 2 | 3 | 2 | 2 | 0 |
| ys | 2 | 3 | 2 | 2 | 1 |
| sq | 2 | 3 | 2 | 2 | 2 |
| ql | 2 | 3 | 2 | 2 | 3 |
| l全 | 2 | 2 | 1 | 2 | 4 |
| 全文 | 2 | 2 | 1 | 2 | 5 |
| 文搜 | 2 | 2 | 1 | 2 | 8 |
| 搜索 | 2 | 2 | 1 | 2 | 11 |
| ql | 2 | 3 | 2 | 2 | 18 |
| my | 2 | 3 | 2 | 2 | 18 |
| ys | 2 | 3 | 2 | 2 | 18 |
| sq | 2 | 3 | 2 | 2 | 18 |
| l提 | 2 | 2 | 1 | 2 | 22 |
| 提供 | 2 | 2 | 1 | 2 | 23 |
| 供了 | 2 | 2 | 1 | 2 | 26 |
| 了具 | 2 | 2 | 1 | 2 | 29 |
| 具有 | 2 | 2 | 1 | 2 | 32 |
| 有许 | 2 | 2 | 1 | 2 | 35 |
| 许多 | 2 | 2 | 1 | 2 | 38 |
| 多好 | 2 | 2 | 1 | 2 | 41 |
| 好的 | 2 | 2 | 1 | 2 | 44 |
| 的功 | 2 | 2 | 1 | 2 | 47 |
| 功能 | 2 | 2 | 1 | 2 | 50 |
| 能的 | 2 | 2 | 1 | 2 | 53 |
| 的内 | 2 | 2 | 1 | 2 | 56 |
| 内置 | 2 | 2 | 1 | 2 | 59 |
| 搜索 | 2 | 2 | 1 | 2 | 60 |
| 文搜 | 2 | 2 | 1 | 2 | 60 |
| 全文 | 2 | 2 | 1 | 2 | 60 |
| 置全 | 2 | 2 | 1 | 2 | 62 |
| my | 2 | 3 | 2 | 3 | 0 |
| ys | 2 | 3 | 2 | 3 | 1 |
| sq | 2 | 3 | 2 | 3 | 2 |
| ql | 2 | 3 | 2 | 3 | 3 |
| l教 | 3 | 3 | 1 | 3 | 4 |
| 教程 | 3 | 3 | 1 | 3 | 5 |
| 学习 | 3 | 3 | 1 | 3 | 12 |
| 习m | 3 | 3 | 1 | 3 | 15 |
| sq | 2 | 3 | 2 | 3 | 18 |
| ql | 2 | 3 | 2 | 3 | 18 |
| my | 2 | 3 | 2 | 3 | 18 |
| ys | 2 | 3 | 2 | 3 | 18 |
| l快 | 3 | 3 | 1 | 3 | 22 |
| 快速 | 3 | 3 | 1 | 3 | 23 |
| 速, | 3 | 3 | 1 | 3 | 26 |
| ,简 | 3 | 3 | 1 | 3 | 29 |
| 简单 | 3 | 3 | 1 | 3 | 32 |
| 单和 | 3 | 3 | 1 | 3 | 35 |
| 和有 | 3 | 3 | 1 | 3 | 38 |
| 有趣 | 3 | 3 | 1 | 3 | 41 |
+------+--------------+-------------+-----------+--------+----------+
50 rows in set

此查询对于故障排除目的很有用。例如,如果一个单词不包括在搜索结果中,则该单词可能没有被编入索引,因为它是一个停止词或者可能是其它原因。

设置ngram令牌大小

在前面的示例可以看到,默认情况下,ngram中的令牌大小(n)为2,要更改令牌大小,请使用ngram_token_size配置选项,值的范围是:1到10。

请注意,较小的令牌大小可使较小的全文搜索索引更快地进行搜索。

因为ngram_token_size是只读变量,因此您只能使用两个选项设置其值:

第一种方式,在启动字符串中:

mysqld --ngram_token_size=1

第二种方式 - 在配置文件中:

[mysqld]
ngram_token_size=1

ngram解析器短语搜索

MySQL将短语搜索转换成ngram短语搜索。 例如,abc被转换为ab bc,它返回包含ab bc和abc的文档。

以下示例显示在posts表中搜索短语:搜索:

SELECT
id, title, body
FROM
posts
WHERE
MATCH (title , body) AGAINST ('搜索' );

执行上面查询语句,得到以下结果 -

mysql> SELECT
id, title, body
FROM
posts
WHERE
MATCH (title , body) AGAINST ('搜索' );
+----+---------------+-------------------------------------------+
| id | title | body |
+----+---------------+-------------------------------------------+
| 1 | MySQL全文搜索 | MySQL提供了具有许多好的功能的内置全文搜索 |
+----+---------------+-------------------------------------------+
1 row in set

用ngram处理搜索结果

自然语言模式

在自然语言模式搜索中,搜索项被转换为ngram值的并集。 假设令牌大小为2或者二进制,则搜索项mysql被转换为我的my ys sq和ql。

SELECT
*
FROM
posts
WHERE
MATCH (title , body) AGAINST ('简单和有趣' IN natural language MODE);

执行上面查询语句,得到以下结果 -

mysql> SELECT
*
FROM
posts
WHERE
MATCH (title , body) AGAINST ('简单和有趣' IN natural language MODE);
+----+-----------+---------------------------+
| id | title | body |
+----+-----------+---------------------------+
| 2 | MySQL教程 | 学习MySQL快速,简单和有趣 |
+----+-----------+---------------------------+
1 row in set

布尔模式

在BOOLEAN MODE搜索中,搜索项被转换成ngram短语搜索。 例如:

SELECT
*
FROM
posts
WHERE
MATCH (title , body) AGAINST ('简单和有趣' IN BOOLEAN MODE);

执行上面查询语句,得到以下结果 -

mysql> SELECT
*
FROM
posts
WHERE
MATCH (title , body) AGAINST ('简单和有趣' IN BOOLEAN MODE);
+----+-----------+---------------------------+
| id | title | body |
+----+-----------+---------------------------+
| 2 | MySQL教程 | 学习MySQL快速,简单和有趣 |
+----+-----------+---------------------------+
1 row in set

ngram通配符搜索

ngram FULLTEXT索引仅包含ngram,因此它不知道短语的开始。执行通配符搜索时,可能会返回意外的结果。

以下规则将应用于使用ngram FULLTEXT搜索索引的通配符搜索:

如果通配符中的前缀短语短于ngram令牌大小,则查询返回所有包含以前缀项为起始的ngram令牌的文档。 例如:

SELECT
id, title, body
FROM
posts
WHERE
MATCH (title , body) AGAINST ('my*' );

执行上面查询语句,得到以下结果 -

mysql> SELECT
id, title, body
FROM
posts
WHERE
MATCH (title , body) AGAINST ('my*' );
+----+---------------+-------------------------------------------+
| id | title | body |
+----+---------------+-------------------------------------------+
| 1 | MySQL全文搜索 | MySQL提供了具有许多好的功能的内置全文搜索 |
| 2 | MySQL教程 | 学习MySQL快速,简单和有趣 |
+----+---------------+-------------------------------------------+
2 rows in set

如果通配符中的前缀短语长于ngram令牌大小,则MySQL将将前缀术语转换为ngram短语,并忽略通配符运算符。 请参阅以下示例:

SELECT
id, title, body
FROM
posts
WHERE
MATCH (title , body) AGAINST ('mysqld*' );

执行上面查询语句,得到以下结果 -

mysql> SELECT
id, title, body
FROM
posts
WHERE
MATCH (title , body) AGAINST ('mysqld*' );
+----+---------------+-------------------------------------------+
| id | title | body |
+----+---------------+-------------------------------------------+
| 1 | MySQL全文搜索 | MySQL提供了具有许多好的功能的内置全文搜索 |
| 2 | MySQL教程 | 学习MySQL快速,简单和有趣 |
+----+---------------+-------------------------------------------+
2 rows in set

在这个例子中,短语“mysqld”被转换为ngram短语:my ys sq ql ld,因此返回包含其中一个短语的所有文档。

处理停止词

ngram解析器不包括在停止词列表中包含停止词的令牌。例如,假设ngram_token_size为2,文档包含abc。 ngram解析器将文档标记为ab和bc。 如果b是一个停用词,则ngram将包含ab和bc,因为它们包含b。

请注意,如果语言不是英语,则必须定义自己的词条列表。 此外,长度大于ngram_token_size的停止词将被忽略。

在本教程中,您已经学会了如何使用MySQL ngram全文解析器来处理表意语言的全文搜索。


您可以捐助,支持我们的公益事业。

1元 10元 50元





认证码: 验证码,看不清楚?请点击刷新验证码 必填



529 次浏览
4次
 捐助