用MySQL实现中文全文搜索|站内搜索

首先我们首先要了解几个概念

  1. MySQL自带英文的全文搜索功能,需要知道fulltext索引和myisam引擎。
  2. 英文全文搜索是靠单词之间的空格实现的。
  3. 英文全文搜索的三个模式以及权重分析。

什么是索引

这边我先做一个说一下索引有什么用?众所周知,你要执行查询,如果没有索引的话,他的搜索方式是检表,即从前到后依次对表进行遍历,最简单的例子

SELECT * FROM users WHERE age=18

这条语句会检查所有表中的数据,直到表没数据了为止,可想而知,如果是数据量较少,速度几乎是不能察觉出来的,但数据量一旦十万百万等,会有明显的延迟。而如果我们给age建立了索引,那么这这个索引的数据将会是这样的。

index age
18 18
19 19
20 20
18 18

此处index为索引标识符,里面存储的是标识符和数据地址,当我们用上面的SQL语句搜索时,步骤是,搜索索引标识符,通过索引标识符,得到所有age=18的数据地址,然后依次取出来。
这样,便省去了检表的操作。
这样,是不是省去了不少时间。
Fulltext的效果就是这样的。

英文全文搜索的三个模式

  1. 自然搜索模式
    MySQL会把搜索字符串解析成一系列的单词,然后搜索出保函这些单词的所在行。
SELECT * FROM index_article WHERE  MATCH(content) AGAINST('中国 北京')

这条语句意思为:搜索索引表中字段为content中包含关键词'中国'、'北京'的文章。

  1. 布尔搜索模式
    在搜索的字符串中可以存在修饰符
SELECT * FROM index_article WHERE MATCH(content) AGAINST('+北京 -朝阳' IN BOOLEAN MODE)

这条语句的意思为搜索索引表中包含'北京'不包含'朝阳'的文章。

  1. 扩展搜索模式
    两次搜索,第一次搜索是自然搜索,第二次搜索会吧第一次搜索中内容中所有次再次进行匹配,从而达到扩大饭的效果。
SELECT * FROM index_article WHERE  MATCH(content) AGAINST('中国 北京' WITH QUERY EXPANSION)

这句的效果是,当第一次搜索时候,搜索到了一句北京朝阳男性市民,第二次扩展搜索时,会将男性市民加入搜索行列,即所有出现这些关键词的时候,都会被搜索到。

权重,怎么计算?

一条语句搞定,但是中文特殊一点,在源码中我有使用到。

SELECT id, MATCH(content) AGAINST('中国 北京') AS weight FROM index_article

之前写的条件变成了权重显示的字段。这条语句的效果为,所有匹配到这两个关键词的内容,会根据次数,密度,比例等指标计算权重。示例如下:

id weight
1 1.2323232123
2 1.3423423423
3 2.3421231231
4 0.2213123123

好,基本知识普及完成,接下来讲下中文全文搜索的思路以及源码

思路解析

项目:做一个博客,可以进行文章上传、展示、站内全文关键词搜索、搜索关键字提示、搜索权重分析。
项目思路:对文章和标题进行分词操作,分词写入数据库的索引表,原数据写入原表;关键词高亮显示,可以使用字符串替换;权重计算关键词出现的次数。

数据表截图

用MySQL实现中文全文搜索|站内搜索_第1张图片
索引表1.png
用MySQL实现中文全文搜索|站内搜索_第2张图片
索引表2.png
用MySQL实现中文全文搜索|站内搜索_第3张图片
原表1.png
用MySQL实现中文全文搜索|站内搜索_第4张图片
原表2.png

多插入几条数据才能实现

展示页面+搜索



    
    
    
    



get_keyword($keywords); unset($keywords);// 释放变量 // 准备sql语句 $sql = "SELECT fid FROM index_article WHERE MATCH(title,content) AGAINST('".$key."')"; $rtn = $model->get_all($sql); unset($sql);// 释放变量 $keys = explode(' ', $key);// 将关键字分割成数组 $res = [];// 建立空数组存储数据 for($i=0;$iget_one($sql); unset($sql);// 销毁变量 //这边做一个相似度评级 $res[$i]['title_num'] = 0; $res[$i]['content_num'] = 0; for($j=0;$j$v){ $weight[$k] = $v['weight']; } @array_multisort($weight,SORT_NUMERIC,SORT_DESC,$res); // 销毁变量 unset($rtn); unset($weight); }else{ $sql = "SELECT * FROM article"; $res = $model->get_all($sql); unset($sql); } $str = ''; for($i=0;$i'.$res[$i]['title'].''; $str .= '

'.$res[$i]['content'].'

'; $str .= '

阅读全文...

'; $str .= '
'; $str .= '
'; } // // $s = ''; // 替换多个关键字 for($i=0;$i".$keys[$i]."",$str); } echo $str; // 释放变量 unset($keys); unset($str); ?>

源码百度云盘地址

http://pan.baidu.com/s/1qXQDTUW

你可能感兴趣的:(用MySQL实现中文全文搜索|站内搜索)