MySQL:全文本和 Bool 文本检索

全文本检索

之前我们使用的通配符或正则表达式进行对关键字的检索,效果很好,但是还是有一些不足的。首先是这样的检索就需要对所有的行进行检索,那么当数据量过多时就会带来性能问题。第二是这样的检索都是完全匹配的,对于模糊查找或者是部分索引而言,没有很强大的功能。这个时候我们就需要更为智能的检索方式,一种不错的选择是使用全文本搜索
全文本搜索有以下注意事项:

  1. 被添加入非用词列表的词和短词(默认 3 个字符及以下的词)将会被自动忽略;
  2. 某个词出现频率很高时将被自动添加入非用词列表;
  3. 检索的表中若行数少于 3 行,不返回任何结果;
  4. 词之间的单引号将被自动忽略,即 “ it's ” 将被认为是 “its”;
  5. MySQL 暂不支持临近操作符。

数据库的搜索基于对数据库引擎的使用,例如 MyISAMInnoDB,但是并不是所有引擎都可以支持全文本检索,例如 InnoDB 引擎就不支持。

建立索引

所谓全文本搜索,并不是对全部的字段进行匹配,而是通过一种名为索引的功能。所谓索引就是在指定的列中指定一些词,用这些词构建一个索引,然后进行检索时就可以根据这些词进行更高效的检索。
在一张表被建立时,可以使用 FULLTEXT 子句启用全文本搜索。通过在该子句中指定构建检索的列,列的数量可以是多个,定义之后 MySQL 将会自动维护索引。当我需要全文本搜索时,就可以根据建立的检索进行匹配。检索可以在建表的时候进行指定,也可以在后续指定。值得一提的是导入数据时,数据的量是过多的,还没有根据需要进行管理。这个时候启用全本文检索的话,对维护检索的开销是很大的,因此全文本搜索应该避免在数据大量变动时启用。

ENGINE 则是用于指定这个表的搜索引擎。

进行搜索

要进行全文本搜索,就需要使用 Match() 函数和 Against() 函数进行联合工作。Match() 函数用于指定被搜索的列,其中指定的列必须已经被 FULLTEXT 子句所建立检索,Against() 函数用于指定搜索的内容。

当然这个搜索也可以使用 LIKE 子句实现,不同在于全文本搜索更为智能。例如全文本搜索的结果会自动排序,例如可以按照检索词的出现位置的前后进行排序,这样对于数据的组织更为方便。这个功能的机理是什么?在全文本搜索时 Match() 函数和 Against() 函数会根据搜索的效果,通过一定的规则计算出一个值,用这个值来度量检索的相关度,依次决定是否回显和次序。

查询拓展

所谓查询拓展,也就是对一个关键字进行相关性查询,即使这个结果没有包含检索词,也能通过一定的规则判断是否相关。要实现这个功能,就需要基于全文本搜索找到所需要的数据,然后通过这些信息为参考进行一次新的全文本搜索,此时的结果将根据相关性返回更多信息。例如对于一次全文本搜索:

对其使用查询扩展,将会返回具有相关性的数据,例如复现的单词。

Bool 文本搜索

使用 布尔方式 (boolean mode) 可以使文本搜索能够附带更多信息,例如需要匹配的词、排斥的词、回显数据优先级等信息。由于这种方式比较精确,因此一般会结合全文本搜索来进行,保证效率。想要使用布尔方式,就需要加入关键字 IN BOOLEAN MODE

布尔操作符

操作符 功能
+ 包含检索词
- 排除检索词
> 包含检索词并提高优先级
< 包含检索词并减少优先级
() 将词组成表达式
~ 取消词的排序值
* 词尾的通配符
"" 定义短语
  • 将被组成的表达式可以被包含、排除或排序。

实例

这个例子可以排除包含指定字符的所有行。

这个例子查找同时包含指定单词的所有行。

这个例子查找存在指定单词的所有行。

这个例子查找同时包含指定短语的所有行。

这个例子给定了指定单词的优先级。

这个例子查找了表达式。

参考资料

《MySQL Crash Course》[英] Ben Forta 著,刘晓霞 钟鸣 译,人民邮电出版社
菜鸟教程——MySQL 教程

posted @ 2021-04-25 10:20  乌漆WhiteMoon  阅读(280)  评论(0编辑  收藏  举报