全文检索FTS不同于模糊查询like,它可以匹配局部的查询条件,即把原查询条件做下分词再去查询。
比如查询条件是:food fruit
,全文检索可以做到返回 包含 food fruit
,food
, fruit
, fruit food
的结果集。
不仅如此,MySQL通过Boolean FTS
还可以做到查询结果包含 food
但不包含 fruit
。
MySQL全文检索概述
目前MySQL支持FULLTEXT
index的存储引擎是 InnoDB
和MyISAM
;
FULLTEXT
index的column列类型只支持:CHAR, VARCHAR, or TEXT
;
FULLTEXT
index 只有在查询语句使用 MATCH() AGAINST()
时候才会生效;
创建 Full-Text Search
MySQL FTS需要创建 FULLTEXT
类型的 index,index要包含所有想要全文检索的列。
创建FTS语法:
CREATE TABLE table_name(
column_list,
...,
FULLTEXT (column1,column2,..)
);
ALTER TABLE table_name
ADD FULLTEXT(column_name1, column_name2,…)
CREATE FULLTEXT INDEX index_name
ON table_name(idx_column_name,...)
删除FTS语法:
ALTER TABLE table_name
DROP INDEX index_name;
创建full-text index 示例:
create fulltext index full_idx_name_author_publisher
on book(name, author, publisher);
MySQL默认的 full-text parser
根据单词间的空格或空白符来分割单词的;但这对于表意语言如中文、韩语和日本语就没作用了。
为了解决这个问题,MySQL提供了ngram full-text parser
,从5.76开始,MySQL把ngram full-text parser
作为server内置插件。
create fulltext index full_idx_name_author_publisher
on book(name, author, publisher) WITH PARSER NGRAM;
注意: 实际使用 ngram parser
的时候,需要关注 stopwords
,最好自定义相关语言的 stop word
列表。
MySQL FTS检索
MySQL全文检索类型:
natural language search type
boolean search type
query expansion search type
Natural-Language检索
select * from book
where
match(name, author, publisher) -- 想要匹配的column列表,需要和创建index时候的column列表一致:列名和个数要一样(顺序可以不一样),不然sql会报错。
against('北京日报') -- 关键字
或
select * from book
where
match(publisher,name, author)
against('北京日报' IN NATURAL LANGUAGE MODE);
如果查询的是中文,创建index的时候要指定用 ngram parser
;
match的column列表需要和创建index时候的column列表一致:列名和个数要一样(顺序可以不一样),不然sql会报错;
IN NATURAL LANGUAGE MODE
是可选项,因为它是默认检索类型。
Boolean FTS
select * from book
where
match(publisher,name, author)
against('北京日报 -青鸟' IN BOOLEAN MODE);
Boolean操作符:
+
: Include, the word must be present.
–
: Exclude, the word must not be present.
>
: Include, and increase ranking value.
<
: Include, and decrease the ranking value.
()
: Group words into subexpressions (allowing them to be included, excluded, ranked, and so forth as a group).
~
: Negate a word’s ranking value.
*
: Wildcard at the end of the word.
“”
: Defines a phrase (as opposed to a list of individual words, the entire phrase is matched for inclusion or exclusion).
Query Expansion
select * from book
where
match(publisher,name, author)
against('老舍' WITH QUERY EXPANSION);
先查出匹配关键字的结果集
从结果集里获取相关词汇
用相关词汇做为条件再次查询
注意:可能会查出很多不相关的结果。
参考资料
MySQL 5.7 中文全文检索使用教程
Full-Text Searches in MySQL: The Good, the Bad and the Ugly
MySQL Boolean Full-Text Searches
12.10 Full-Text Search Functions
How to Use Full-Text Searches in My
作者:编码者频道
微信公众号:编码者频道
扫描二维码(或者长按识别二维码)关注公众号获取最新信息。
本文版权归作者和博客园共有,欢迎转载,
转载请保留原文链接,谢谢!