方案:问答搜索

1. 搜索结果列表,高亮显示搜索关键词内容

2. 用户输入内容,点击搜索
    
    2.1 获取用户的搜索内容;
    
    2.2 调用分词服务,获取对搜索内容的分词;
    
    2.3 先查询是否已经存在这些关键词内容的缓存,有则直接取结果;否,进行下一步;
    
    2.4 如果 2.2 返回的分词数大于 5 个,则取 5 个关键词的问答帖子交集,判断数量是否 >= 30 条;
        不够,则逐次丢弃最后的关键词,再次进行查询,直到关键词的个数减到只有 1 个为止;
        
        2.4.1 对 2.4 中的多次结果进行去从,以及进行帖子的权重计算
        (
            问答帖子的质量计算:
                Q = α * T + β * S + γ * A , α = 0.2 , β = 0.5 , γ = 0.3 ;
                T - 时间; S - 点赞数 ; A - 回答数;
                T = (当前的时间秒戳 - 帖子的发帖时间) / 7*86400;
        )
        
    2.5 将 2.4 中的问答结果写入 Redis ,10 分钟失效;(key - hnb:qa:search_result , 帖子)
    
    2.6 读取 2.5 Redis 结果,展示到页面 // 问答搜索
public function getQuestionBySearch($arr_keyWords , $arr_keyWeight , $start , $num)
{
$arr_temple_keyWords = $arr_keyWords; count($arr_keyWords) > 8 ? $len = 8 : $len = count($arr_keyWords); // redis 中的 key 值
$key = 'hnb:qa:search:qa_score:' . implode('_' , array_splice($arr_temple_keyWords , 0 , $len)); // 读取 redis 中 key = hnb-search:'关键词',... 有没有缓存.
$exists = Hnb_Model_Qa_Question_Cache::getInstance()->existsKey($key); if($exists)
{
$arr_questionInfo = unserialize($exists); } else { $arr_questionInfo = array();
$arr_question_ids = array();
$arr_label_in_question = array();
do{ $arr_keyWords = array_splice($arr_keyWords , 0 , $len--);
$arr_result = Hnb_Model_Qa_Question_Cache::getInstance()->getSearchRelativeQuestion($arr_keyWords , $start , $num); // 问答帖子
foreach($arr_result as $question)
{
// 去掉重复的问答
if(!in_array($question['id'] , $arr_question_ids))
{
$arr_question_ids[] = $question['id']; // 权重计算
$question['score'] = pow(2 , $len);
$this->_logicQaWeight($question , $arr_keyWords , $arr_keyWeight);
$arr_questionInfo[] = $question;
}
} } while((count($arr_questionInfo) < 100) && $len); // 存在数据时
if($arr_questionInfo)
{
// 权重排序
//uasort($arr_questionInfo , array($this , 'cmp'));
usort($arr_questionInfo , array($this , 'cmp'));
// 保存临时数据
//Hnb_Model_Qa_Question_Cache::getInstance()->saveTempleData($key , $arr_questionInfo , $timeOutSecond = 600);
// 设定该临时数据的失效时间
}
} return $arr_questionInfo;
} // 按帖子的权重排序
private function cmp($a , $b)
{
if($a['score'] == $b['score'])
{
return 0;
}
return ($a['score'] > $b['score']) ? -1 : 1;
}
// 问答帖子的权重计算逻辑
private function _logicQaWeight(&$questionInfo , $arr_keyWords , $arr_keyWeight)
{
$a = 0.2; // 发帖时间
$b = 0.5; // 点赞数
$c = 0.3; // 回复数
//$d = ..; // 匹配度因子
$b = $c = 0;
$timeLine = 30 * 86400; // $minus = time() - $questionInfo['create_time']; // 向下取整
$t = floor($minus / $timeLine); $tParam = 2 * pow(0.5 , $t);
// 用户回答
$user_answers = Hnb_Model_Qa_Answer::getInstance()->getAnswerInfoByQuestion($questionInfo['id']);
// 顾问回答权重计算
if($user_answers)
{
is_string($user_answers) ? $user_answers = unserialize($user_answers) : '';
$praise_num = null;
foreach($user_answers as $answer)
{
$praise_num += $answer['praise_num'];
}
} else {
$praise_num = 0;
} // 匹配度因子计算
$this->_matchingQARate($questionInfo , $arr_keyWords , $arr_keyWeight); $weight = $a * $tParam + $b * $praise_num + $c * $questionInfo['answer_num'];
$questionInfo['all_praise_num'] = $praise_num;
$questionInfo['keywords'] = implode(',' , $arr_keyWords);
$questionInfo['params'] = '时间-' . ($a * $tParam) . '##tParam-' . $tParam. '## 点赞数-' . ($b * $praise_num) . '## 回复数-' . ($c * $questionInfo['answer_num']);
$questionInfo['score'] = $questionInfo['score'] + $weight;
//print_r($questionInfo);
} // 帖子的匹配度
public function _matchingQARate(&$questionInfo , $arr_keyWords , $arr_keyWeight)
{
// 1. 发送搜索内容到分词服务 $arr_kwIntersect_result = array_intersect($arr_keyWords , $questionInfo['keyword']);
echo '交集';
print_r($arr_kwIntersect_result);
// 2. 获取到返回的分词与权重
$arr_format_wordInfo = Hnb_Model_Search::getInstance()->formatWordInfo($questionInfo['keyword2']); // 帖子关键词的权重,注意次序
$w = array();
foreach($arr_format_wordInfo as $wordInfo)
{
if(in_array($wordInfo['keyword'] , $arr_kwIntersect_result))
{
$w[] = $wordInfo['weight'];
}
} // 搜索内容分词的权重,注意次序
$y = array(); foreach($arr_keyWeight as $weightInfo)
{
if(in_array($weightInfo['keyword'] , $arr_kwIntersect_result))
{
$y[] = $weightInfo['weight'];
}
} print_r($w);
echo '<br />';
print_r($y);
echo '###############';
$element = null;
foreach($w as $key => $v)
{
$element += $v * $y[$key];
}
echo $element; // 3. 与搜索出来的帖子做交集 // 4. 计算帖子的匹配度 /*
* 计算公式:
* 3 中的交集作为分子
* 3 中的帖子与 2 的分词权重
*/
}

PHP 实现简单搜索功能的更多相关文章

  1. asp.net mvc 简单搜索功能

    View中代码: <input type="text" class="searchText" id="searchText"/> ...

  2. Flutter 实现简单搜索功能

    先建立一个主文件,继承StatelessWidget,然后在home属性中加入SearchBarDemo,这是一个自定义的Widget,主要代码都在这个文件中. import 'package:flu ...

  3. ElasticSearch(五):简单的ElasticSearch搜索功能

    这里主要是一些简单的ElasticSearch的搜索功能,复杂的搜索,比如过滤,聚合等以后单独在写 1. 搜索全部 GET book/_search 直接搜索全部,下面是对搜索结果的详细介绍:默认情况 ...

  4. jQuery实现简单前端搜索功能

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  5. Vue下简单分页及搜索功能

    最近利用Vue和element ui仿写了个小页面,记一哈分页和搜索功能的简单实现. 首页   emmmm..... 搜索框输入..... 搜索完成 数据是直接写在这里面的: cardPhoto:[ ...

  6. jquery实现简单的搜索功能

    管理系统中需要实现导航列表的搜索功能,写了一个简单的小栗子: <!DOCTYPE html> <html lang="en"> <head> & ...

  7. 简单三步-实现dede站内搜索功能

    第一步:找到对应的搜索模板的代码 我们都知道,dede有自带的搜索功能,我们只要找到对应的模板,然后把我们想要的代码拿出来就行了.具体如下: 首先进入templets-->default--&g ...

  8. ElasticSearch 5学习(4)——简单搜索笔记

    空搜索: GET /_search hits: total 总数 hits 前10条数据 hits 数组中的每个结果都包含_index._type和文档的_id字段,被加入到_source字段中这意味 ...

  9. Android搜索功能的案例,本地保存搜索历史记录......

    开发的APP有一个搜索功能,并且需要显示搜索的历史记录,我闲暇之余帮她开发了这个功能,现把该页面抽取成一个demo分享给大家. 实现效果如图所示:  本案例实现起来很简单,所以可以直接拿来嵌入项目中使 ...

随机推荐

  1. php代码编译的实现

    1.php是解析型的高级语言,zend内核使用c语言实现,有main函数,php脚本就是输入,内核处理后输出结果,内核将php脚本翻译成c程序可识别的opcode就是php的编译. c语言的编译将c代 ...

  2. 黄聪:Windows 64位系统中安装Android SDK“系统找不到指定的文件Java.exe”解决方法

    明明已经在64位window7中安装好了64位版本的jdk,为什么android SDK安装程序却识别不到jdk呢?先看看报错: Java SE Development Kit (JDK) not f ...

  3. Java 8 Lambda表达式之方法引用 ::双冒号操作符

    双冒号运算符就是java中的方法引用,方法引用的格式是类名::方法名. 这里只是方法名,方法名的后面没有括号“()”.--------> 这样的式子并不代表一定会调用这个方法.这种式子一般是用作 ...

  4. 找到一篇关于2.4/5G信道的新介绍

    关于部分手机无法搜索到5G wifi信号的解决方法第一次在论坛发基础理论贴,希望能普及关于5G wifi的基础知识.         发此贴的原因是基于本人突然发现:MX3刷了3.4.1系统后,搜索不 ...

  5. MOBA游戏的网络同步技术

    转自:http://www.gameres.com/750888.html 在5月13日Unite 2017 案例分享专场上,蓝港互动<闹闹天宫>项目组的主程序陈实分享了MOBA游戏的网络 ...

  6. java构造函数是否可继承,以及子类构造函数可否不使用super调用超类构造函数

    问题一:java的构造函数能否被继承? 笔者初学java看的一本书说:“java的子类自然的继承其超类的“非private成员”. 通常java的构造函数被设置为public的(若你不写构造函数,ja ...

  7. Creating an Android Project(创建一个android项目)

    一个android项目包含了你的应用程序中的所有源代码文件,我们可以通过android sdk tools轻松地创建一个拥有默认文件跟文件夹的android项目. 这部分课程我们将展示两种创建andr ...

  8. 读Understanding the Linux Kernel, 3rd Edition有感

    14.3.2.2. Avoiding request queue congestion Each request queue has a maximum number of allowed pendi ...

  9. 利用MessageFormat实现短信模板的匹配

    其实没什么技术含量,因为老是想不起来,所以在此文做下记录. 通常我们的应用系统中都会有很多短信的发送,或者是信息邮件等的推送,而这些信息却有着相同的共性,比如只是用户名换了下. 像下面这条,除了红色字 ...

  10. 通过PicturreId获取图片路径(Url)

    1.直接使用接口服务 _pictureService.GetPictureUrl((int)entity.SponsorPictureId); //entity是具体查询出来的实体对象 Sponsor ...