Full-Text Search Functions 全文搜索功能(一)
什么full-text ?
我们已经了解了index(索引)可以在主键或者建立一个索引对于快速查找一个列中是否含有某个值,这个index 很在行,但是想在一个data block 中快速找到字符[串] 就要用FULL-TEXT 这个技术了。
基本语法格式
MATCH (col1,col2,...) AGAINST (expr [search_modifier])
search_modifier:
{
IN NATURAL LANGUAGE MODE
| IN NATURAL LANGUAGE MODE WITH QUERY EXPANSION
| IN BOOLEAN MODE
| WITH QUERY EXPANSION
}
语法讲解:
Full-text searching is performed using MATCH() ... AGAINST syntax. MATCH() 用逗号分隔要被检索的列名,AGAINST后跟要检索的内容,后边的search_modifier:按照什么方式进行检索。
这里有三个主要的检索方式(下边会分别讲解他们的区别),默认的是:IN NATURAL LANGUAGE MODE
FULLTEXT 的一些有关概念
一直将理论太累了,以实际列子说明,下边就是手册中的一个建立全文索引的列子。
mysql> CREATE TABLE articles (
-> id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
-> title VARCHAR(200),
-> body TEXT,
-> FULLTEXT (title,body)
-> ) ENGINE=MyISAM;
mysql> SELECT * FROM articles
-> WHERE MATCH (title,body)
-> AGAINST ('database' IN NATURAL LANGUAGE MODE);
+----+-------------------+------------------------------------------+
| id | title | body |
+----+-------------------+------------------------------------------+
| 5 | MySQL vs. YourSQL | In the following database comparison ... |
| 1 | MySQL Tutorial | DBMS stands for DataBase ... |
+----+-------------------+------------------------------------------+
类型就是 FULLTEXT。
Fulltext 只能创建在MYISAM 表,支持检索的列的类型 CHAR ,VARCHAR,TEXT
如上述code 可以直接在表创建时候创建 或者 Alter 时候穿件(ALTER TABLE `table_name` ADD FULLTEXT ( `column`) ),有时候进行表复制的时候,最好复制数据,之后创建full-text 不然创建fulltext 的表要被考入需要花很长时间。
附:三种检索方式
NATURAL LANGUAGE MODE 全文检索中的默认类型。把查询字符串作为一个短语,如果有不少于50%的行匹配,则认为没有匹配的。想去掉50%的限制,可以修改文件myisam/ftdefs.h里的#define GWS_IN_USE GWS_PROB为#define GWS_IN_USE GWS_FREQ。
可以看到这种方式大小写不敏感,可以修改它的collation latin1----> latin1_bin . 还看到了一个相关性,默认的时候就是按相关性排序的。
mysql> select title, match(title,body) against('database') from articles where match(title,body) against('database');
+-------------------+---------------------------------------+
| title | match(title,body) against('database') |
+-------------------+---------------------------------------+
| MySQL vs. YourSQL | 0.662664592266083 |
| MySQL Tutorial | 0.655458331108093 |
+-------------------+---------------------------------------+
相关性排序的依据: 行中的词总数、行中不同的词个数、集合中全部的词总数、查询到的行数。
只能进行单表查询,多表你用 IN BOOLEAN MODE 。
补充:(这个没有验证)
create table article (
articleID int not null auto_increment primary key,
title varchar(255),
body text,
fulltext (title,body)
);
select title from article
where match (title,body) against ('merge acquisition acquire takeover');
搜索所有在title ,body 这两列中包含 merge /acquisition/acquire/takeover at least one word 的行的title 。
mysql 现在不支持所谓的“stemming” 技术, acquire acquisition acquired 都必须分开写。
mysql> SELECT * FROM articles
-> WHERE MATCH (title,body)
-> AGAINST ('MySQL' IN NATURAL LANGUAGE MODE);
Empty set (0.00 sec)
Why ? 为什么没有找到,是不会显示 50% 安全栅,已经把这个超过出现在50% 以上的行数的词 列为-------stopword 。
B. IN BOOLEAN MODE 没有50%的限制。可以用包含特定意义的操作符,如 +、-、"",作用于查询字符串上。查询结果不是以相关性排序的。
Operator Meaning
+ This word is compulsory.
- This word must not appear.
< This word is less important.
> This word is more important.
( ) Group words together as a subexpression.
~ This word may appear, but it has a negative effect on ranking.
* Wildcard suffix. For example, merge will not match merger, but merge* will match both merge and merger. May be used only at the end of a word.
" " This is a phrase. Matches only exactly the same content in the same order.
C. |IN NATURAL LANGUAGE MODE WITH QUERY EXPANSION 对自然语言检索的一种改动(自动相关性反馈),当查询短语太短时有用。先进行自然语言检索,然后把最相关的一些(系统变量ft_query_expansion_limit的值)行中的词添加到查询字符串中进行二次自然语言检索,查询得到的行作为结果返回。
分析三种检索方式的不同
标准的已经详述了,现在是BOOLEAN MODE:
mysql> SELECT * FROM articles WHERE MATCH (title,body)
-> AGAINST ('+MySQL -YourSQL' IN BOOLEAN MODE);
+----+-----------------------+-------------------------------------+
| id | title | body |
+----+-----------------------+-------------------------------------+
| 1 | MySQL Tutorial | DBMS stands for DataBase ... |
| 2 | How To Use MySQL Well | After you went through a ... |
| 3 | Optimizing MySQL | In this tutorial we will show ... |
| 4 | 1001 MySQL Tricks | 1. Never run mysqld as root. 2. ... |
| 6 | MySQL Security | When configured properly, MySQL ... |
+----+-----------------------+-------------------------------------+
Boolean 的特征:
它没有50% 的显示
同时没有自动排序(按照相关性)
及时你没有对特定列进行fulltext指示,但是还可以搜索,就是slow 点。