(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;
②进行全文本搜索
SELECT note_text
FROM productnotes
WHERE Match(note_text) Against('rabbit');
输出:
note_text
I like rabbit
rabbit is so cute
注:使用完整的Match()说明传递给Match()的值必须与 FULLTEXT()定义中的相同。如果指定多个列,则必须列出它们(而且次序正确)。另:除非使用BINARY方式, 否则全文本搜索不区分大小写。
SELECT note_text
FROM productnotes
WHERE note_text LIKE '%rabbits%';
二者区别为:前者(使用全文本搜索)返回以文本匹配的良好程度排序的数据。两个行都包含词rabbit,但包含词rabbit作为 第3个词的行的等级比作为第20个词的行高。这很重要。全文本搜索的一 个重要部分就是对结果排序。具有较高等级的行先返回(因为这些行很 可能是你真正想要的行)。
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 的两个行每行都有一个等级值,文本中词靠前的行的等级值比词靠后的 行的等级值高。
注:排序多个搜索项 如果指定多个搜索项,则包含多数匹配词的 那些行将具有比包含较少词(或仅有一个匹配)的那些行高的 等级值
③ 使用查询扩展
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索引也可以使用布尔文文本搜索,但是会随着数据量的增加而降低性能
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)的行
如上两个全文本搜索布尔操作符-和*,- 排除一个词,而* * 是截断操作符(可想象为用于词尾的一个通配符)。
下列出支持的所有全文本布尔操作符:
布尔操作符 说明
+ 包含,词必须存在
- 排除,词必须不出现
> 包含,而且增加等级值
< 包含,且减少等级值
() 把词组成子表达式(允许这些子表达式作为一个组被包含、排除、排列等)
~ 取消一个词的排序值
* 词尾的通配符
"" 定义一个短语(与单个词的列表不一样,它匹配整个短语以便包含或排除这个短语)
SELECT note_text
FROM productnotes
WHERE Match(note_text) Against('+rabbit +bait' IN BOOLEAN MODE);
SELECT note_text
FROM productnotes
WHERE Match(note_text) Against('rabbit bait' IN BOOLEAN MODE);
SELECT note_text
FROM productnotes
WHERE Match(note_text) Against(' "rabbit bait" ' IN BOOLEAN MODE);
SELECT note_text
FROM productnotes
WHERE Match(note_text) Against(' >rabbit
SELECT note_text
FROM productnotes
WHERE Match(note_text) Against(' +safe +(
注:在布尔方式中,不按等级值降序排序返回的行。
⑤ 全文本搜索的使用说明
【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