一、取出所有文章的tags,并组成数组
public function getAllGroupByArticleId(){
//缓存查询数据,因为这个是全表数据,而且不更新文章不会变化,便是每次推荐都要从数据库里获取一次数据,对性能肯定会有影响,所以做个缓存。
if($cache = CacheHelper::getCache()){
return $cache;
}
$query_result = $this->query('select articleid, GROUP_CONCAT(tagid) as tags from tag_map GROUP BY articleid');
$result = [];
foreach($query_result as $key => $value){
//用articleid 做key ,值是该id下的所有tagID数组。
$result[$value['articleid']] = explode(",",$value['tags']);
}
CacheHelper::setCache($result, 86400);
return $result;
}
二、利用返回结果,计算相似度,返回相关ID
/**
* [更据指定文章返回相似的文章推荐]
* @param $articleid 指定的文章ID
* @param $top 要返回的推荐条数
* @return Array 推荐条目数组
*/
function getArticleRecommend($articleid, $top = 5){
if($cache = CacheHelper::getCache()){
return $cache;
}
try{
$articleid = intval($articleid);
$m = new TagMapModel();
$all_tags = $m->getAllGroupByArticleId();//调用上面的函数返回所有文章的tags
$finded = $all_tags[$articleid];//因为上面是包含所有文章了,所以肯定包含了当前文章。
unset($all_tags[$articleid]);//把当前文章从数组中删除,不然自己和自己肯定是相似度最高了。
$jaccard_arr = []; //用于存相似度
foreach ($all_tags as $key => $value) {
$intersect =array_intersect($finded, $value); //计算交集
$union = array_unique(array_merge($finded, $value)); //计算并集
$jaccard_arr[$key] = (float)(count($intersect) / count($union));
}
arsort($jaccard_arr); //按相似度排序,最相似的排最前面
$jaccard_keys = array_keys($jaccard_arr);//由于数组的key就是文章id,所以这里把key取出来就可以了
array_splice($jaccard_keys, $top);//获取前N条推荐
//到这里我们就已经得到了,最相似N篇文章的ID了,接下去的工作就是通过这几个ID,从数据库里把相关信息,查询出来就可以了
$articleModels = new \Api\Model\ArticleModel();
$recommendArticles = $articleModels->getRecommendByTag($jaccard_keys);
CacheHelper::setCache($recommendArticles, 604800); //缓存7天
return $recommendArticles;
} catch (\Exception $e) {
throw new \Exception("获取推荐文章错误");
}
}
声明:
本站所有资源均来源于网络收集,一切版权©归原作者所有,请保留原版权信息。
所有资源不排除存在BUG,残缺或加密的可能,请三思后再买,否则购买后一率不能退款;
本站分享仅供参考学习和演示,禁止商用,如需商用,请从正规渠道选择购买正版!使用正版!支持正版!