【MySQL必知必会】学习笔记Day9&2.12&D18章&P119-130页
16、全文本搜索
(1)理解全文本搜索
在使用全文本搜索时,MySQL不需要分别查看每个行,不需要分别分析和处理每个词。MySQL创建指定列中各词的一个索引,搜索可以针对这些词进行。这样,MySQL可以快速有效地决定哪些词匹配(哪些行包含它们), 哪些词不匹配,它们匹配的频率,等等
(2)使用全文本搜索
为了进行全文本搜索,必须索引被搜索的列,而且要随着数据的改变不断地重新索引。在对表列进行适当设计后,MySQL会自动进行所有 的索引和重新索引。
在索引之后,SELECT可与Match()和Against()一起使用以实际执行搜索。
① 启用全文本搜索支持
CREATE TABLE productnotes
(
note_id int NOT NULL AUTO_INCREMENT,
prod_id char(10) NOT NULL ,
note_date datetime NOT NULL ,
note_text text NULL,
PRIMARY KEY(note_id),
FULLTEXT(note_text)
) ENGINE=My ISAM;
- 上述列中有一个名为note_text的列,为了进行全文本搜索,MySQL根据子句FULLTEXT(note_text)的指示列对它进行索引。
- MySQL自动维护该索引,在增加、更新或删除行时,索引随之自动更新。
注:不要在导入数据时使用索引
②进行全文本搜索
- 在索引之后,使用两个函数Match()和Against()执行全文本搜索
- 其中Match()指定被搜索的列,Against()指定要使用的搜索表达式。
SELECT note_text
FROM productnotes
WHERE Match(note_text) Against('rabbit');
输出:
note_text
I like rabbit
rabbit is so cute
- 此SELECT语句检索单个列note_text。由于WHERE子句,一个全文本搜索被执行
- Match(note_text)指示MySQL针对指定的 列进行搜索
- Against('rabbit')指定词rabbit作为搜索文本
注:使用完整的Match()说明传递给Match()的值必须与 FULLTEXT()定义中的相同。如果指定多个列,则必须列出它们(而且次序正确)。另:除非使用BINARY方式, 否则全文本搜索不区分大小写。
- 上面语句也可以用下面的:
SELECT note_text
FROM productnotes
WHERE note_text LIKE '%rabbits%';
二者区别为:前者(使用全文本搜索)返回以文本匹配的良好程度排序的数据。两个行都包含词rabbit,但包含词rabbit作为 第3个词的行的等级比作为第20个词的行高。这很重要。全文本搜索的一 个重要部分就是对结果排序。具有较高等级的行先返回(因为这些行很 可能是你真正想要的行)。
- eg:
SELECT note_text,
Match(note_text) Against('rabbit') AS rank
FROM procedures;
这里,在SELECT而不是WHERE子句中使用Match()和Against()。这使所有行都被返回(因为没有WHERE子句)。Match()和Against() 用来建立一个计算列(别名为rank),此列包含全文本搜索计算出的等级值。等级由MySQL根据行中词的数目、唯一词的数目、整个索引中词的 总数以及包含该词的行的数目计算出来。正如所见,不包含词rabbit的 行等级为0(因此不被前一例子中的WHERE子句选择)。确实包含词rabbit 的两个行每行都有一个等级值,文本中词靠前的行的等级值比词靠后的 行的等级值高。
注:排序多个搜索项 如果指定多个搜索项,则包含多数匹配词的 那些行将具有比包含较少词(或仅有一个匹配)的那些行高的 等级值
③ 使用查询扩展
- 首先,进行一个基本的全文本搜索,找出与搜索条件匹配的所有 行;
- 其次,MySQL检查这些匹配行并选择所有有用的词
- 再其次,MySQL再次进行全文本搜索,这次不仅使用原来的条件, 而且还使用所有有用的词
SELECT note_text
FROM productnotes
WHERE Match(note_text) Against('anvils');
上面结果返回1行
SELECT note_text
FROM productnotes
WHERE Match(note_text) Against('anvils' WITH QUERY EXPANSION);
上面结果返回7行
查询扩展增加了返回的行数,但也增加了实际上并不想要的行的数目
注:表中的行越多(这些行中的文本就越多),使用 查询扩展返回的结果越好
④ 布尔文本搜索
MySQL支持全文本搜索的另外一种形式,称为布尔方式。以布尔方式,可以提供关于如下内容的细节:
- 要匹配的词
- 要排斥的词(如果某行包含这个词,则不返回该行,即使它包含其他指定的词也是如此);
- 排列提示(指定某些词比其他词更重要,更重要的词等级更高);
- 表达式分组;
- 另外一些内容
注:即使没有FULLTEXT索引也可以使用布尔文文本搜索,但是会随着数据量的增加而降低性能
- eg:
SELECT note_text
FROM productnotes
WHERE Match(note_text) Against('heavy' IN BOOLEAN MODE);
此全文本搜索检索包含词heavy的所有行(有两行)。其中使用
了关键字IN BOOLEAN MODE,但实际上没有指定布尔操作符, 因此,其结果与没有指定布尔方式的结果相同。
为了匹配包含heavy但不包含任意以rope开始的词,可使用如下查询:
SELECT note_text
FROM productnotes
WHERE Match(note_text) Against('heavy -rope*' IN BOOLEAN MODE);
这次只返回一行。这一次仍然匹配词heavy,但-rope明确地
指示MySQL排除包含rope(任何以rope开始的词,包括 ropes)的行
如上两个全文本搜索布尔操作符-和,- 排除一个词,而 * 是截断操作符(可想象为用于词尾的一个通配符)。
下列出支持的所有全文本布尔操作符:
布尔操作符 说明
+ 包含,词必须存在
- 排除,词必须不出现
> 包含,而且增加等级值
< 包含,且减少等级值
() 把词组成子表达式(允许这些子表达式作为一个组被包含、排除、排列等)
~ 取消一个词的排序值
* 词尾的通配符
"" 定义一个短语(与单个词的列表不一样,它匹配整个短语以便包含或排除这个短语)
- eg:这个搜索匹配包含词rabbit和bait的行
SELECT note_text
FROM productnotes
WHERE Match(note_text) Against('+rabbit +bait' IN BOOLEAN MODE);
- eg:没有指定操作符,这个搜索匹配包含rabbit和bait中的至少一个词的行
SELECT note_text
FROM productnotes
WHERE Match(note_text) Against('rabbit bait' IN BOOLEAN MODE);
- eg:这个搜索匹配短语rabbit bait而不是匹配两个词rabbit和 bait
SELECT note_text
FROM productnotes
WHERE Match(note_text) Against(' "rabbit bait" ' IN BOOLEAN MODE);
- eg:匹配rabbit和carrot,增加前者的等级,降低后者的等级
SELECT note_text
FROM productnotes
WHERE Match(note_text) Against(' >rabbit <bait ' IN BOOLEAN MODE);
- eg:匹配safe 和combination,降低后者的等级
SELECT note_text
FROM productnotes
WHERE Match(note_text) Against(' +safe +(<combination)' IN BOOLEAN MODE);
注:在布尔方式中,不按等级值降序排序返回的行。
⑤ 全文本搜索的使用说明
- 在索引全文本数据时,短词(具有3个或3个以下字符的词)被忽略且从索引中排除。(如需要,这个数目可以更改)
- MySQL带有一个内建的非用词(stopword)列表,这些词在索引全文本数据时总是被忽略。如需要,可以覆盖这个列表
- 许多词出现的频率很高,搜索它们没有用处,因此MySQL规定了一条50%规则,如果一个词出现在50%以上 的行中,则将它作为一个非用词忽略。50%规则不用于IN BOOLEAN MODE。
- 如果表中的行数少于3行,则全文本搜索不返回结果
- 忽略词中的单引号。例如,don't索引为dont。
- 不具有词分隔符(包括日语和汉语)的语言不能恰当地返回全文本搜索结果。
- 如前所述,仅在MyISAM数据库引擎中支持全文本搜索。
【MySQL必知必会】系列笔记:
【MySQL必知必会1-4章】学习笔记Day1
【MySQL必知必会5-7章】学习笔记Day2
【MySQL必知必会8-9章】学习笔记Day3
【MySQL必知必会10章】学习笔记Day4
【MySQL必知必会11-12章】学习笔记Day5
【MySQL必知必会13章】学习笔记Day6
【MySQL必知必会14-16章】学习笔记Day7
【MySQL必知必会17章】学习笔记Day8
网友评论