PHP实现站内搜索笔记
发布于 分类 PHP
22天前 有1个用户阅读过
博客从wordpress更换nocolite后一直没加上搜索功能,PS:nocolite是我学习PHP并用于生产环境的PHP项目。但因为nocolite最开始是为英文网站开发的,虽然后续也增加了分词,英文搜索也比较精准,因为英文直接用空格分词,所以很明显那个分词不适合中文搜索。
说干就干,以下是PHP实现中文站内搜索的笔记。
目标要求:
1.尽量精准2.尽量少的代码
根据这个目标要求,就扩展一下最基础的mysql的like语句直接匹配字符串,通过分词使其更精准一点。
要点:
1.只搜索标题2.分词暂时使用中文分词api
通过API 字符串得到分词,需要去掉重复的单词,以及单个的中文字符减少非重要关键词。下面是SCWS的中文分词API实现方法。
//http://www.xunsearch.com/scws/api.php
function scws_api($str){
$url = 'http://www.xunsearch.com/scws/api.php';
$data = array(
'data'=>$str,
'respond'=>'json',
'ignore'=>'yes',
);
$json_data = postData($url, $data);
$array = json_decode($json_data,true);
if ($array['status']=='ok'){
$array=$array['words'];
foreach($array as $v){
//排除单个汉字,缩小范围
if($v['attr']!='en' && $v['len']<4){
}else{
$arr[]=$v['word'];
}
}
}else{
return array($str);
}
return $arr;
}
function postData($url, $data){
$ch = curl_init();
$timeout = 300;
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
$handles = curl_exec($ch);
curl_close($ch);
return $handles;
}
获取到分词后,接下来就是根据分词拼接sql的like字符串了,重点在于关键词两两匹配,必须同时满足2个分词。能适当提高精准度。
//分词拼接SQL进行搜索
$array=scws_api($keywords);
//去重复
$array=array_unique($array);
//全匹配 and
foreach($array as $v){
$where1.="" and title like '%$v%'";
}
//两两匹配
$result = array();
foreach ( $array as $v1){
foreach ( $array as $v2){
if($v1!=$v2){
$where2.=" or (title like '%$v1%' and title like '%$v2%')";
}
}
}
//拼接
$where="1".$where1.$where2;
虽然比较简陋且有些许缺陷,但好歹算比较满意了。有了搜索范围,接下来就简单了,你可以试下本站右上角的搜索。 ----更新补充-------------------------------
不用API,使用PHP扩展可以很大程度提高分词速度:Linux安装中文分词SCWS的PHP扩展
-- The End --