利用mysql的全文索引实现模糊查询
时间:2010-10-14 来源:yudotyang
使用mysql的全文索引来实现like一样的模糊查询。关于mysql全文索引的基础这里不多说,可以去查看手册。
下面举例说明。
1.首先我们实现中文的模糊匹配,比如我要搜索“北京china”,把所有包含“北京china”的相关文章都搜索出来。
首先,大家最容易想到的就是用like模式匹配了。假设我们的这个字段叫做title.表名称叫做ft_table 则最简单的语句应该是:select * from ft_table where title like "%北京china%" 这样。
但是这样存在的这样一个缺陷,就是数据库要进行全表扫描,不能使用索引,如果数据量大了的话,搜索效率非常低下。
改进方案:利用mysql的全文索引来达到同样的目的。
1.分词。我们知道全文索引的基础是以词为基础的,所以我们第一步要做的就是分词。
2.怎么分词。一想到分词我们肯定会说用很多开源的现成分词工具。这里我们的分词指的是将字符串中的每个字作为一个词来对待。比如“北京china”我们会分成“北 京 c h i n a"。因为只有这样我们才能让任意两个相邻的字组成一个词来达到模糊匹配的结果。 如果按传统的分词是这样”北京 china“,那如果我们搜索”京“的话,就搜索不到这个词,也就无法找到结果。但是在数据库中确实存在包含”京“的内容。
3.区位码转化。在mysql的全文索引中,是不支持中文的。所以我们必须要将中文转换成mysql可以支持的字符--区位码,因为每个汉字的区位码是唯一的,而且是4位的。所以我们将每个单字都转换成对应的区位码。
4.如何处理英文字符。在mysql中,对于类似这样的词”a,ag,b,c...“等等是忽略不计的。那么如果我们输入”a“的话,怎么样才能将包含”a“的内容都搜索出来呢?对,就是将英文字符也转换成对应的ascii码,因为英文的ascii码是用数字表示的,而且范围是0-127,所以,mysql不会忽略。
5.解决mysql全文索引最小词长度的限制。默认情况下,全文索引的最小词的长度是4个字节。即ft_min_word_len=4.但是每个英文字符的ascii码最长也就3位数字,即三个字节。所以我们应该是将 ft_min_word_len的值更改成3。但是有的ascii码值是两位或者一位的,所以我们在转换的时候应该将不足三位的数字补齐成三位,加前导0数字即可。
6.如何将任意两个相邻的字看成一个词来进行搜索呢? 利用mysql中的模式against('"keyword1 keyword2"')
例如,我们要的分词列表为”北 京 c h i n a“。输入的关键词为"京c" ,则利用这样的模式against('"京 c"' in boolean mode) 即可得到包含”京c“的内容。对于用户来说,搜索到的就是”京c“的关键词的结果。
the end。
首先,大家最容易想到的就是用like模式匹配了。假设我们的这个字段叫做title.表名称叫做ft_table 则最简单的语句应该是:select * from ft_table where title like "%北京china%" 这样。
但是这样存在的这样一个缺陷,就是数据库要进行全表扫描,不能使用索引,如果数据量大了的话,搜索效率非常低下。
改进方案:利用mysql的全文索引来达到同样的目的。
1.分词。我们知道全文索引的基础是以词为基础的,所以我们第一步要做的就是分词。
2.怎么分词。一想到分词我们肯定会说用很多开源的现成分词工具。这里我们的分词指的是将字符串中的每个字作为一个词来对待。比如“北京china”我们会分成“北 京 c h i n a"。因为只有这样我们才能让任意两个相邻的字组成一个词来达到模糊匹配的结果。 如果按传统的分词是这样”北京 china“,那如果我们搜索”京“的话,就搜索不到这个词,也就无法找到结果。但是在数据库中确实存在包含”京“的内容。
3.区位码转化。在mysql的全文索引中,是不支持中文的。所以我们必须要将中文转换成mysql可以支持的字符--区位码,因为每个汉字的区位码是唯一的,而且是4位的。所以我们将每个单字都转换成对应的区位码。
4.如何处理英文字符。在mysql中,对于类似这样的词”a,ag,b,c...“等等是忽略不计的。那么如果我们输入”a“的话,怎么样才能将包含”a“的内容都搜索出来呢?对,就是将英文字符也转换成对应的ascii码,因为英文的ascii码是用数字表示的,而且范围是0-127,所以,mysql不会忽略。
5.解决mysql全文索引最小词长度的限制。默认情况下,全文索引的最小词的长度是4个字节。即ft_min_word_len=4.但是每个英文字符的ascii码最长也就3位数字,即三个字节。所以我们应该是将 ft_min_word_len的值更改成3。但是有的ascii码值是两位或者一位的,所以我们在转换的时候应该将不足三位的数字补齐成三位,加前导0数字即可。
6.如何将任意两个相邻的字看成一个词来进行搜索呢? 利用mysql中的模式against('"keyword1 keyword2"')
例如,我们要的分词列表为”北 京 c h i n a“。输入的关键词为"京c" ,则利用这样的模式against('"京 c"' in boolean mode) 即可得到包含”京c“的内容。对于用户来说,搜索到的就是”京c“的关键词的结果。
the end。
相关阅读 更多 +