MySQL 5.7 中文全文检索


在 MySQL 5.7.6 之前,全文索引只支持英文全文索引,不支持中文全文索引,需要利用分词器把中文段落预处理拆分成单词,然后存入数据库。
MySQL 5.7.6 开始,MySQL内置了ngram全文解析器,用来支持中文、日文、韩文分词。
本文使用的MySQL 版本是 5.7.24InnoDB数据库引擎。


ngram全文解析器

ngram就是一段文字里面连续的n个字的序列。

ngram全文解析器能够对文本进行分词,每个单词是连续的n个字的序列。

例如,用ngram全文解析器对“恭喜发财”进行分词:

n=1: '恭', '喜', '发', '财'
n=2: '恭喜', '喜发', '发财'
n=3: '恭喜发', '喜发财'
n=4: '恭喜发财'

MySQL 中使用全局变量 ngram_token_size 来配置 ngram 中 n 的大小,它的取值范围是1到10,默认值2。通常ngram_token_size设置为要查询的单词的最小字数。如果需要搜索单字,就要把ngram_token_size设置为1。在默认值是2的情况下,搜索单字是得不到任何结果的。因为中文单词最少是两个汉字,推荐使用默认值2。

全局变量 ngram_token_size 的两种设置方法:

【方式1】:使用启动命令 mysqld 时,传参如下:

mysqld --ngram_token_size=2

【方式2】:在修改MySQL配置文件 my.ini 中,末尾增加一行 ngram_token_size 的参数设置:

[mysql]
# 设置mysql客户端默认字符集
default-character-set=utf8
[mysqld]
#设置3306端口
port = 3306server_id=100
# 设置mysql的安装目录
basedir=D:\mysql-5.7.24-winx64
# 设置mysql数据库的数据的存放目录
datadir=D:\mysql-5.7.24-winx64\data
# 允许最大连接数
max_connections=200
# 服务端使用的字符集默认为8比特编码的latin1字符集
character-set-server=utf8
# 创建新表时将使用的默认存储引擎
default-storage-engine=INNODB# 全文检索分词数
ngram_token_size=2


创建全文索引

1、建表 t_article

建表语句如下:

/*Navicat Premium Data TransferSource Server         : localhostSource Server Type    : MySQLSource Server Version : 50724Source Host           : localhost:3306Source Schema         : test_dbTarget Server Type    : MySQLTarget Server Version : 50724File Encoding         : 65001Date: 07/07/2019 19:54:33
*/SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;-- ----------------------------
-- Table structure for t_article
-- ----------------------------
DROP TABLE IF EXISTS `t_article`;
CREATE TABLE `t_article`  (`id` int(11) NOT NULL AUTO_INCREMENT,`title` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,`content` text CHARACTER SET utf8 COLLATE utf8_general_ci NULL,PRIMARY KEY (`id`) USING BTREE,FULLTEXT INDEX `fulltext_title_content`(`title`, `content`) WITH PARSER `ngram`
) ENGINE = InnoDB AUTO_INCREMENT = 15 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;-- ----------------------------
-- Records of t_article
-- ----------------------------
INSERT INTO `t_article` VALUES (1, '八荣八耻 1', '以热爱祖国为荣、以危害祖国为耻');
INSERT INTO `t_article` VALUES (2, '八荣八耻 2', '以服务人民为荣、以背离人民为耻');
INSERT INTO `t_article` VALUES (3, '八荣八耻 3', '以崇尚科学为荣,以愚昧无知为耻');
INSERT INTO `t_article` VALUES (4, '八荣八耻 4', '以辛勤劳动为荣,以好逸恶劳为耻');
INSERT INTO `t_article` VALUES (5, '八荣八耻 5', '以团结互助为荣,以损人利己为耻');
INSERT INTO `t_article` VALUES (6, '八荣八耻 6', '以诚实守信为荣,以见利忘义为耻');
INSERT INTO `t_article` VALUES (7, '八荣八耻 7', '以遵纪守法为荣,以违法乱纪为耻');
INSERT INTO `t_article` VALUES (8, '八荣八耻 8', '以艰苦奋斗为荣,以骄奢淫逸为耻');
INSERT INTO `t_article` VALUES (9, '满江红', '靖康耻,尤未雪');
INSERT INTO `t_article` VALUES (10, '第一生产力', '科学技术是第一 生产力');
INSERT INTO `t_article` VALUES (11, '团结互助', '团结就是力量');
INSERT INTO `t_article` VALUES (12, 'Blue Red', 'Red Black');
INSERT INTO `t_article` VALUES (13, '我是奇迹 1', '你好,我是奇迹2');
INSERT INTO `t_article` VALUES (14, '恭喜发财', '你好');SET FOREIGN_KEY_CHECKS = 1;

2、创建全文索引

创建字段 titlecontent 的联合全文索引,语句如下:

alter table `t_article` add fulltext index fulltext_title_content(`title`,`content`) WITH PARSER ngram; 

重连数据库,刷新查看索引的创建情况:

3、全文检索查询

1)查询 title 或者 content 中包含“祖国”的记录,查询语句如下:

select *, MATCH (title, content) AGAINST ('祖国') as score
from t_article where MATCH (title, content) AGAINST ('祖国' IN NATURAL LANGUAGE MODE);

查询结果如下:

2)查询 title 或者 content 中包含“团结劳动”的记录,查询语句如下:

select *, MATCH (title, content) AGAINST ('团结劳动') as score
from t_article where MATCH (title, content) AGAINST ('团结劳动' IN NATURAL LANGUAGE MODE);

查询结果如下(查询结果,默认会按照得分 score ,从高到低排序):

3)查询 title 或者 content 中包含“为荣”的记录,查询语句如下:

select *, MATCH (title, content) AGAINST ('为荣') as score
from t_article where MATCH (title, content) AGAINST ('为荣' IN NATURAL LANGUAGE MODE);

查询结果如下(可以看到,此处得分是一样的):

4、特殊情况

1)查询单个汉字

比如,查询 title 或者 content 中包含“”的记录,查询语句如下:

select *, MATCH (title, content) AGAINST ('力') as score
from t_article where MATCH (title, content) AGAINST ('力' IN NATURAL LANGUAGE MODE);

查询结果如下:

从上可以看到,查不到结果。原因是设置的全局变量 ngram_token_size 的值为 2。

如果想查询单个汉字,需要在配置文件 my.ini 中修改 ngram_token_size = 1 ,重启 mysqld 服务。

使用如下命令查询 ngram_token_size 的设置情况:

show VARIABLES like 'ngram_token_size';

查询结果如下:

此时,再次执行上面的单个汉字“”查询语句,结果如下(由于记录id = 10 中包含两个“力”,记录id = 11 中只有一个“力”。所以,查询结果中,前者得到的分数是后者的两倍):

2)查询单个字段

比如,查询字段 content 中包含“诚实”,查询语句如下:

select *, MATCH (content) AGAINST ('诚实') as score
from t_article where MATCH (content) AGAINST ('诚实' IN NATURAL LANGUAGE MODE);

查询结果报错如下:

select *, MATCH (content) AGAINST ('诚实') as score
from t_article where MATCH (content) AGAINST ('诚实' IN NATURAL LANGUAGE MODE)
> 1191 - Can't find FULLTEXT index matching the column list
> 时间: 0.002s

原因是没有给字段 content 单独创建全文检索的索引。

给字段 content 创建全文检索索引,语句如下:

alter table `t_article` add fulltext index fulltext_content(`content`) WITH PARSER ngram;

执行结果如下:

再次执行 查询字段 content 中包含“诚实”,查询结果如下:

同理,如下需要单独对字段 title 进行全文检索,需要给字段 title 创建全文检索的索引,创建语句如下:

alter table `t_article` add fulltext index fulltext_title(`title`) WITH PARSER ngram; 

结果如下:

5、全文检索模式

常用的全文检索模式有两种:

1、自然语言模式(NATURAL LANGUAGE MODE)

自然语言模式是 MySQL 默认的全文检索模式。

自然语言模式不能使用操作符,不能指定关键词必须出现或者必须不能出现等复杂查询。

2、BOOLEAN 模式(BOOLEAN MODE)
BOOLEAN 模式可以使用操作符,可以支持指定关键词必须出现或者必须不能出现或者关键词的权重高还是低等复杂查询。

BOOLEAN 模式,举例如下:

'apple banana'
无操作符,表示或,要么包含apple,要么包含banana'+apple +juice'
必须同时包含两个词'+apple macintosh'
必须包含apple,但是如果也包含macintosh的话,相关性会更高。'+apple -macintosh'
必须包含apple,同时不能包含macintosh。'+apple ~macintosh'
必须包含apple,但是如果也包含macintosh的话,相关性要比不包含macintosh的记录低。'+apple +(>juice <pie)'
查询必须包含apple和juice或者apple和pie的记录,但是apple juice的相关性要比apple pie高。'apple*'
查询包含以apple开头的单词的记录,如apple、apples、applet。'"some words"'
使用双引号把要搜素的词括起来,效果类似于like '%some words%',
例如“some words of wisdom”会被匹配到,而“some noise words”就不会被匹配。

举例说明:

1)查询字段 content 中包含 “团结”“力量”的语句如下:

select *, MATCH (content) AGAINST ('+团结 +力量') as score
from t_article where MATCH (content) AGAINST ('+团结 +力量' IN BOOLEAN MODE);

查询结果如下:

2)查询字段 content 中包含 “团结”,但不包含“力量”的语句如下:

select *, MATCH (content) AGAINST ('+团结 -力量') as score
from t_article where MATCH (content) AGAINST ('+团结 -力量' IN BOOLEAN MODE);

查询结果如下:

3)查询字段 conent 中包含“团结”或者“力量”的语句如下:

select *, MATCH (content) AGAINST ('团结 力量') as score
from t_article where MATCH (content) AGAINST ('团结 力量' IN BOOLEAN MODE);

查询结果如下:

6、注意

1)只能在类型为 CHARVARCHAR 或者 TEXT 的字段上创建全文索引。

2)全文索引只支持 InnoDBMyISAM 引擎。

3)MATCH (columnName) AGAINST ('keywords')。MATCH()函数使用的字段名,必须要与创建全文索引时指定的字段名一致

如上面的示例,MATCH (title,content)使用的字段名与全文索引t_article(title,conent)定义的字段名一致。

如果要对 title 或者 content 字段分别进行查询,就需要在 title 和 content 字段上分别创建新的全文索引。

4)MATCH()函数使用的字段名只能是同一个表的字段,因为全文索引不能够跨多个表进行检索。

5)如果要导入大数据集,使用先导入数据,在表上创建全文索引的方式,要比先在表上创建全文索引再导入数据的方式快很多。

转载于:https://www.cnblogs.com/miracle-luna/p/11147859.html

MySQL 5.7 中文全文检索相关推荐

  1. MySQL中文全文检索

    一.概述 MySQL全文检索是利用查询关键字和查询列内容之间的相关度进行检索,可以利用全文索引来提高匹配的速度. 二.语法 1 2 MATCH (col1,col2,...) AGAINST (exp ...

  2. php mysql 全文检索_MySQL中文全文检索

    一.概述 MySQL全文检索是利用查询关键字和查询列内容之间的相关度进行检索,可以利用全文索引来提高匹配的速度. 二.语法 MATCH (col1,col2,...) AGAINST (expr [s ...

  3. mysql全文查询中文_MySQL-中文全文检索

    一.概述 MySQL全文检索是利用查询关键字和查询列内容之间的相关度进行检索,可以利用全文索引来提高匹配的速度. 二.语法 例如:SELECT * FROM tab_name WHERE MATCH ...

  4. MySQL中文全文检索demoSQL

    一.概述       MySQL全文检索是利用查询关键字和查询列内容之间的相关度进行检索,可以利用全文索引来提高匹配的速度. 二.语法       MATCH (col1,col2,...) AGAI ...

  5. mysql5.7中文全文检索,让MySQL支持中文全文检索

    因为中文词间并没有明显的区隔,所以中文的分词是按照字典.词库的匹配和词的频度统计,或是基于句法.语法分析的分词,而MySQL并不具备此功能,所以MySQL对中文全文检索的支持几乎为零. 目前很多网站和 ...

  6. mysql sphinx windows安装_Sphinx在windows下安装使用[支持中文全文检索]

    前一阵子尝试使用了一下Sphinx,一个能够被各种语言(PHP/Python/Ruby/etc)方便调用的全文检索系统.网上的资料大多是在 linux环境下的安装使用,当然,作为生产环境很有必要部署在 ...

  7. Mysql支持中文全文检索的插件mysqlcft-应用中的问题

    MySQL目前版本的全文检索没有对中文很好的支持,但可以通过安装mysqlcft插件来实现,具体的安装使用方法:http://blog.s135.com/post/356/ mysqlcft的官方网站 ...

  8. mysql中文全文检索从入门到放弃

    like全匹配模糊查询不能使用索引一直是sql查询的一个棘手的问题,那么mysql的全文检索真的能解决这个问题吗? 背景 最近,在工作中遇到一个查询优化的问题,简化的sql如下: SELECT* FR ...

  9. coreseek mysql.sock_Coreseek + Sphinx + Mysql + PHP构建中文检索引擎

    安装前首先安装依赖的软件包 yuminstall make gcc g++ gcc-c++ libtool autoconf automake imake  libxml2-devel expat-d ...

  10. coreseek mysql_coreseek (sphinx)+ Mysql + Thinkphp搭建中文搜索引擎详解

    一, 前言 1,研究coreseek的动机 我有一个自己的笔记博客,经常在上面做一些技术文章分析.在查询一些文章的时候,以前只能将要查询的内容去mysql中用like模糊匹配.在文章多了的情况下,这样 ...

最新文章

  1. Python的IDE:利用MyEclipse2017软件的PyDev插件实现Python编程
  2. [转载]SQL Server 2005 Data Mining简介
  3. Koa -- 基于 Node.js 平台的下一代 web 开发框架
  4. 数据结构与算法--这个需求很简单怎么实现我不管(发散思维)
  5. placeholder=请输入用户名(六位数字加英文字母)
  6. php修改音频文件_php获取mp3文件信息时长修改
  7. realme Q5系列核心规格曝光:80W快充加持 同价位绝无仅有
  8. Neural Motifs: Scene Graph Parsing with Global Contex
  9. ASUS笔记本型号命名
  10. zotero与Obsidian联动笔记(一):ob中直接调用zotero的文献,并生成笔记
  11. 《算法导论》第九章.中位数和顺序统计量
  12. 永动机实现了?超导体的故事了解一下
  13. 使用scp把另外一台服务器上的文件夹/文件拷贝到当前服务器
  14. (四) l立创EDA之封装库的创建
  15. 关于MathType生成的公式插入Word显示错误的原因和处理
  16. 前端安全系列:如何防止XSS攻击?
  17. android获取卡1卡2电话号码
  18. 麦克风办理FCC认证
  19. PVE7.21安装流程
  20. 《腾讯桌球》日活300万!盘点LayaAir引擎的3D小游戏!

热门文章

  1. 关于纳什均衡与博弈论
  2. 聚合支付公司利楚扫呗获得腾讯、蚂蚁亿元入股
  3. ElasticSearch系列十:ElasticSearch搜索技术深入讲解之搜索模板,搜索建议和地理位置搜索
  4. unity3d 地面印花_unity冬季场景地面地形白雪纹理材质贴图游戏素材Winter Ground Pack v1.1...
  5. Java学习记录之StringBuilder类
  6. 华为计算机主板,华为鲲鹏920台式机主板亮相:性能配置都亮眼
  7. afudos备份bios不动_映泰主板刷新AMI BIOS失败自救
  8. [生产力]必备的全局文件搜索工具
  9. B016 - 基于51单片机的公交车语音报站_点阵广告屏
  10. An illegal reflective access operation has occurred警告