一提到搜索,一般人都会想到select的like的模糊查询,如果再细致一些,可能直接会去想到用Sphinx等一些三方插件什么的,本文用了一些其他的方法,可以自己实现一些较为多样的查询。
本文是主要实现:根据前端返回的关键词,来匹配上数据库较为接近的回答,并根据相似度进行筛选排序。
本文采用了yii框架,以接口形式展现。
代码函数:
数据库数据:
查询结果:
会返回比模糊查询更多的,更精确一些的数据
因为这个会需要提前便利数据库,查询出所有的回答,然后再对数组进行处理,因此,不太适用于,拥有庞大海量数据的模式。
其中,有一些冲突的点,similar_text($a,$b)会返回相似的字符的个数,因为汉字的原因,最少一个相同字符的时候,最小为3,所以,设置的为>2,如果有英文的需要,把英文单独分离出来,判断即可。
代码:
public static function GetReturnKeywordAnswerDetail($content)
{
//将准备的回答中的信息全部都取出来
$result = BaseSelfReply::find()->select('scene,reply_content')->asArray()->limit(10)->all();
//var_dump($result);die;
//将回答进行过滤筛查
if(empty($content)){$content ="上班";}
foreach($result as $key){
//判断两个字符串之间是否相互包含或者是有共同的字符串
if (strpos($key['scene'],$content) !==false || strpos($content,$key['scene']) !==false ||similar_text($key['scene'],$content) >2){
//$percent为两个字符串相似度,为0~100之间
similar_text($content,$key['scene'],$percent);
$key['desc'] = $percent;
$answerArr[] = $key;
}
}
//已经将与用户的文字相关的回答取出,按照相似度高低排序
$count = count($answerArr)-1;
for($i=0;$i<$count;$i++){
if($answerArr[$i]['desc']<$answerArr[$i+1]['desc']){
//相似度权值互换
$answerArr2[$i]['desc'] = $answerArr[$i]['desc'];
$answerArr[$i]['desc']=$answerArr[$i+1]['desc'];
$answerArr[$i+1]['desc']=$answerArr2[$i]['desc'];
//关键字互换
$answerArr2[$i]['scene'] = $answerArr[$i]['scene'];
$answerArr[$i]['scene']=$answerArr[$i+1]['scene'];
$answerArr[$i+1]['scene']=$answerArr2[$i]['scene'];
//回答的问题互换
$answerArr2[$i]['reply_content'] = $answerArr[$i]['reply_content'];
$answerArr[$i]['reply_content']=$answerArr[$i+1]['reply_content'];
$answerArr[$i+1]['reply_content']=$answerArr2[$i]['reply_content'];
}
}
return $answerArr;
}