时间:2021-07-01 10:21:17 帮助过:29人阅读
MYSQL全文搜索通过 MATCH() 函数完成。
下面举一简单例子:
1、新建数据表:
CREATE TABLE fulltext_sample(copy TEXT,FULLTEXT(copy)) TYPE=MyISAM;
这里的copy就是一个fulltext类型的字段,如果建表的时候没有添加全文检索字段,也可以通过alert来添加,如:
ALTER TABLE fulltext_sample ADD FULLTEXT(copy)
2、插入数据:
INSERT INTO fulltext_sample VALUES ('It appears good from here'), ('The here and the past'), ('Why are we hear'), ('An all-out alert'), ('All you need is love'), ('A good alert');
3、数据检索:
SELECT * FROM fulltext_sample WHERE MATCH(copy) AGAINST('love');
上面就是mysql的全文检索功能,注意:在全文索引上进行搜索是不区分大小写的。
下面再看如何实现中文全文检索。
fulltext字段是以词语为单位,词语之间需要用空格隔开,而汉语的句子中各个词语之间并不会用空格隔开,因此我们需要对中文进行分词,这也就是为什么上面需要强词用到中文分词扩展模块。
但是尽管对中文进行分词,MYSQL还是不能通过MATCH来实现中文的全文检索,这需要通过一定的方法来进行转换,一个比较简单实用的方法是采用下面这个函数(当然还有更好的),它将中文进行了urlencode转换。
function q_encode($str) { $data = array_filter(explode(" ",$str)); $data = array_flip(array_flip($data)); foreach ($data as $ss) { if (strlen($ss)>1 ) $data_code .= str_replace("%","",urlencode($ss)) . " "; } $data_code = trim($data_code); return $data_code; }
将转换过后的内容保存至事先定义好的fulltext字段。同样,在查询的时候也需要将查询的关键词进行同样方法的转换。
PHP+Mysql实现UTF8全文搜索的方法
本文讲解一下如何在海量的数据中能够快速的进行全文检索呢?MySQL提供了一个全文索引功能,也就是把字段设置上FULLTEXT索引属性,然后通过SELECT的MATCH AGAINST语句进行查找。
我们开发的一个纯英文站点TouchUs - The Global Yellow Pages & Business Directory(www.touchus.org)就是利用MySQL的这一功能,实现了对十多万条数据的平均全文检索时间小于0.5秒。但是在开发TouchUs的中文网站??城市黄页网时(www.city39.cn),碰到了新的问题。原来英文排版时词和词之间是通过空格区分的,FULLText可以完全支持,但是对中文或者是东亚文字就没有这么简单了,因为中文的词和词之间并没有明显的分隔,所以MySQL不支持中文字符的全文检索。
如何让MySQL也能支持中文的全文检索呢?偶然间产生了一个思路,那就是能不能在中文分词后,通过对中文进行编码转化成英文字符,这样就在中英文间建立一个特定的联系,然后再进行全文检索,这样不就实现了中文的全文索引了吗?经过试验,答案是肯定的。下面是在城市黄页网中实现的具体过程:
1. 建立一个单独的索引表,比如对应members表,我们建立一个members_index表。
用户信息表(members) 用户信息全文索引表(members_index)
User_id user_id
User_name index_intro
User_introduction
在members_index表的index_intro中加入fulltext索引。
2. 对用户信息表(members)的User_introduction字段内容进行中文分词处理
中文分词的处理过程,可以参考简易中文分词系统http://www.ftphp.com/scws/,在城市黄页网中,我们采用了scws的PHP扩展模块方式来实现中文分词。scws的php扩展模块安装非常简单,只需简单编译配置后即可使用。在具体的php代码中,我们写了如下的函数来实现分词后将分词结果用空格进行连接。
//中文分词函数 function str_fc($str) { $so = scws_new(); $so->set_charset('utf8'); // 这里没有调用 set_dict 和 set_rule 系统会自动试调用 ini 中指定路径下的词典和规则文件 $so->send_text($str); while ($tmp = $so->get_result()) { foreach ( $tmp as $ss ){ $s = trim($ss[word]); if ( $s ) $mystr .= trim($ss[word]) . " "; //echo urlencode(trim($ss[word])) . " "; } } return $mystr; }
该函数返回就是用空格连接的分词结果。
3. 对分词结果进行编码,可以采用多种编码方式,比如base64编码、urlencode编码、汉字转拼音等,对gb2312甚至可以采用区位码编码方式。考虑到存储空间以及便利性,我们采用了PHP的urlencode编码方式。需要注意的是,在编码前,我们可以去掉重复的分词来节约存储空间,编码后要去掉编码结果中的%符号,因为urlencode采用RFC 1738???行编码,会产生很多%,而%在MySQL是通配符。下面是编码过程用到的PHP代码
$data = str_fc($data); //中文分词 $data = array_filter(explode(" ",$data)); //删除数组空项 $data = array_flip(array_flip($data)); //删除重复项 //对分词结果进行urlcode编码 foreach ( $data as $ss ) { if (strlen($ss)>1 ) $data_code .= str_replace("%","",urlencode($ss)) . " "; }
这里的$data_code就是编码后的结果。把编码结果根据user_id存入用户信息全文索
引表(members_index)
4. 在进行搜索处理时,首先对用户输入的关键字进行同样的分词编码处理,然后通过MySQL的SELECT的MATCH AGAINST语句进行全文快速检索,根据检索结的user_id即可调用用户信息表(members)中的原始数据进行显示,而没有必要进行一次解码重组。
以上MySQL UTF8中文全文检索方法.