使用全文索引的场景:
全文索引通过建立倒排索引来快速匹配文档,MySQL 5.6 + 版本引入此功能,全文索引将连续的字母、数字和下划线当做一个单词,分割单词一般用空格、逗号、句号。
简介:
CREATE TABLE
语句中给出FULLTEXT索引定义,或稍后使用ALTER TABLE或CREATE INDEX添加该定义全文索引的三种类型
IN NATURAL LANGUAGE MODE
,通过MATCH AGAINST
传递某个特定的字符串来进行检索IN BOOLEAN MODE
,支持操作符,如+
表示包含,-
表示不包含WITH QUERY EXPANSION
,相当于自然语言模式下的一个扩展,执行两次检索,第一次使用给定短语检索,第二次是结合第一次相关性比较高的行进行检索创建全文索引的三种方式
FULLTEXT(column1, column2, ...)
ALTER TABLE table_name ADD FULLTEXT INDEX index_name (column1, column2, ...);
CREATE FULLTEXT INDEX index_name ON table_name (column1, column2, ...);
配置
编辑my.ini
配置文件,增加:
# MySQL全文索引查询关键词最小长度限制
[mysqld]
ft_min_word_len = 1
存储方式
full inverted index
:会占用更多的空间,因为它不仅会存储单词和单词所在文档的ID,还会存储单词所在文档的ID中具体的位置。inverted file index
:只存储单词及对应的单词所在文档。节省空间,但是查找时,只能根据关键字得到相应文档,再进行查找InnoDB会把单词拆分进行存储,查找时,根据单词匹配(默认是英文符号)。有些词是不能索引查询的,就称之为停用词,stopword。查询系统的默认停止词:
SELECT * FROM information_schema.INNODB_FT_DEFAULT_STOPWORD;
添加自定义的停用词:
information_schema.INNODB_FT_INDEX_TABLE
information_schema.INNODB_FT_INDEX_CACHE
information_schema.INNODB_FT_DEFAULT_STOPWORD
计算原理:
排序:等级由MySQL根据行中词的数目、唯一词的数目、整个索引中词的总数以及包含该词的行的数目计算出来
建表语句:
CREATE TABLE full_text_test (
title VARCHAR(80),
FULLTEXT (title)
);
插入准备好的数据:
INSERT INTO full_text_test
VALUES
('It''s a beautiful night we''re looking for something dumb to do'),
('Hey baby I think I wanna marry you'),
('Is it the look in your eyes or is it this dancing juice'),
('Who cares baby I think I wanna marry you'),
('Well I know this little chapel on the boulevard'),
('We can go ooooo'),
('No one will know ooo'),
('Oh come on girl'),
('Who cares if we''re trashed'),
('Got a pocket full of cash we can blow whoa whoa'),
('Shots of patrol whoa whoa'),
('And it''s on girl'),
('Don''t say no no no no no'),
('Just say yeah yeah yeah yeah yeah'),
('If you''re ready like I''m ready'),
('I''ll go get the ring'),
('Let the choir bell sing like ooh ooh ooh'),
('So what you wanna do ooh ooh'),
('Let''s just run girl'),
('If we wake up and you want to break up'),
('That''s cool ooh ooh'),
('No I won''t blame you ooh ooh'),
('It was fun girl'),
('And we''ll go go go go go'),
('Just say I do ooh ooh ooh'),
('Tell me right now baby'),
('Tell me right now baby baby');
Natural Language,也是默认的检索模式,表示查询带有指定word的文档,下面2种方式是等价:
SELECT title, MATCH(title) AGAINST('baby') AS relevance FROM full_text_test order by relevance desc;
SELECT title, MATCH(title) AGAINST('baby' in NATURAL LANGUAGE MODE) AS relevance FROM full_text_test order by relevance desc;
Match()
指定被搜索的列,Against()
指定要使用的搜索表达式,传递给Match()
的值必须与FULLTEXT()
定义中的相同。如果指定多个列,则必须列出它们(而且次序正确), 除非使用BINARY方式,否则全文本搜索不区分大小写。
表示字符串前后的字符有特殊含义。+
表示存在,-
符号表示不存在。如,查找含有marry,不含有cares的记录:
SELECT title FROM full_text_test WHERE MATCH(title) AGAINST('+marry' in BOOLEAN MODE);-- 返回2条记录
SELECT title FROM full_text_test WHERE MATCH(title) AGAINST('+marry -cares' in BOOLEAN MODE);-- 返回1条记录
符号解释:
+
:必须出现-
:必须不出现,用来排除其他操作符的结果,如果只指定这个,将什么都不返回无符号
:默认情况,代表或,自动分词搜索。和没有指定IN BOOLEAN MODE的结果一样@distance
:用来测试两个或两个以上的单词是否都在一个指定的距离内,在@距离前指定双引号中的搜索词,例如MATCH(col1) AGAINST(‘“word1 word2 word3” @8’ IN BOOLEAN MODE>
:提高该条匹配数据的权重值<
:降低该条匹配数据的权重值()
:相当于表达式分组,和数学中的表达式一个道理~
:将其相关性由正转负,表示拥有该字会降低相关性,如+apple ~macintosh
先匹配apple,但如果同时包含macintosh,排名会靠后*
:通配符,只能在字符串后面使用"
:完全匹配,被双引号包起来的单词必须整个被匹配示例:
apple banana
包含apple或banana其中一个
+apple +juice
必须同时包含apple和juice
+apple macintosh
包含apple,但是如果同时包含macintosh会给更高的排序
+apple -macintosh
包信apple但是不包含macintosh
+apple ~macintosh
包含apple,如果同时包含macintosh降低权重
apple*
包含apple单词的行,applesauce
等都会被匹配到
"some words"
完全匹配some words的行
+apple +(>turnover
添加WITH QUERY EXPANSION
或IN NATURAL LANGUAGE MODE WITH QUERY EXPANSION
启用,它会执行两次检索,第一次使用给定短语检索,第二次是结合第一次相关性比较高的行进行检索。
如下查询语句:
SELECT * FROM full_text_test WHERE MATCH (title) AGAINST ('fruit' WITH QUERY EXPANSION);
执行时,会先执行一次基本查询,即自然语言查询:
SELECT * FROM full_text_test WHERE MATCH (title) AGAINST ('fruit' IN NATURAL LANGUAGE MODE);
然后第二次查询会将第一次查询的结果作为输入短语,最后根据相关性降序获取查询结果。
也就是说,某条字符串如果不含有fruit
关键词短语,如果含有apple
关键词,则也可能出现在查询扩展的结果集里。