MySQL 中文全文检索

php 中文分词 splitwordphp

SCWS 中文分词mysql

VicWord一个纯php的分词git

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

ngram全文解析器

ngram就是一段文字里面连续的n个字的序列。ngram全文解析器可以对文本进行分词,每一个单词是连续的n个字的序列。例如,用ngram全文解析器对“生日快乐”进行分词:sql

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的两种设置方法:
一、启动mysqld命令时app

mysqld --ngram_token_size=2

 

二、修改MySQL配置文件dom

[mysqld] 
ngram_token_size=2

 

建立全文索引

一、建立表的同时建立全文索引函数

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;

 

二、经过 alter table 的方式来添加工具

ALTER TABLE articles ADD FULLTEXT INDEX ft_index (title,body) WITH PARSER ngram;

 

三、直接经过create index的方式

CREATE FULLTEXT INDEX ft_index ON articles (title,body) WITH PARSER ngram;

 

全文检索模式

经常使用的全文检索模式有两种:
一、天然语言模式(NATURAL LANGUAGE MODE) ,
天然语言模式是MySQL 默认的全文检索模式。天然语言模式不能使用操做符,不能指定关键词必须出现或者必须不能出现等复杂查询。
二、BOOLEAN模式(BOOLEAN MODE)
BOOLEAN模式可使用操做符,能够支持指定关键词必须出现或者必须不能出现或者关键词的权重高仍是低等复杂查询。

示例

SELECT * FROM articles
WHERE MATCH (title,body)
AGAINST ('一路 一带' IN NATURAL LANGUAGE MODE);

// 不指定模式,默认使用天然语言模式
SELECT * FROM articles
WHERE MATCH (title,body)
AGAINST ('一路 一带'); 
示例

 

上面的示例返回结果会自动按照相关性排序,相关性高的在前面。相关性的值是一个非负浮点数,0表示无相关性。

// 获取相关性的值
SELECT id,title,
MATCH (title,body) AGAINST ('手机' IN NATURAL LANGUAGE MODE) AS score
FROM articles
ORDER BY score DESC; 
// 获取匹配结果记录数
SELECT COUNT(*) FROM articles
WHERE MATCH (title,body)
AGAINST ('一路 一带' IN NATURAL LANGUAGE MODE);

 

可使用BOOLEAN模式执行高级查询。

// 必须包含"腾讯"
SELECT * FROM articles
WHERE MATCH (title,body)
AGAINST ('+腾讯' IN BOOLEAN MODE);
示例
// 必须包含"腾讯",可是不能包含"通信工具"
SELECT * FROM articles
WHERE MATCH (title,body)
AGAINST ('+腾讯 -通信工具' IN BOOLEAN MODE); 
 

下面的例子演示了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”就不会被匹配。

 

注意
  • 只能在类型为CHAR、VARCHAR或者TEXT的字段上建立全文索引。
  • 全文索引只支持InnoDB和MyISAM引擎。
  • MATCH (columnName) AGAINST ('keywords')。MATCH()函数使用的字段名,必需要与建立全文索引时指定的字段名一致。如上面的示例,MATCH (title,body)使用的字段名与全文索引ft_articles(title,body)定义的字段名一致。若是要对title或者body字段分别进行查询,就须要在title和body字段上分别建立新的全文索引。
  • MATCH()函数使用的字段名只能是同一个表的字段,由于全文索引不可以跨多个表进行检索。
  • 若是要导入大数据集,使用先导入数据再在表上建立全文索引的方式要比先在表上建立全文索引再导入数据的方式快不少,因此全文索引是很影响TPS的。
相关文章
相关标签/搜索