本文爲Redis系列開始,全程代碼實踐乾貨滿滿,喜歡能夠關注我html
像博客、論壇等內容網站讓優質內容獲得足夠曝光,是提升網站吸引力的重要方法。 今天咱們就常常佔據網站C位的 熱門文章列表
這一場景來詳細分析。git
首先產品經理來找你談( wa )需( keng )求:github
玩笑歸玩笑哈,多維度的綜合排序確實時常遇到~ 怎麼辦呢?redis
咱們引出一個 熱度
的概念,它實際上是個表明文章的受歡迎程度的分數
。 咱們把 發佈時間、點贊、評論、瀏覽量... 經過公式轉化爲熱度,再根據它來排序便可bash
文章按時間倒序排序,咱們能夠理解了一個隨時間衰減
的評分,這裏可使用Unix時間。而點贊、評論、瀏覽量...則乘以本身的權重(常量
),加上發佈時間就等於文章評分測試
首先準備文章數據
:id:1文章最先發布,id:5文章最晚網站
[ 'id' => 1, 'title' => 'article 1', 'link' => 'http://article 1', 'user_id' => 1, 'votes' => 0, 'publish_time' => 1571190843 ],
[ 'id' => 2, 'title' => 'article 2', 'link' => 'http://article 2', 'user_id' => 1, 'votes' => 0, 'publish_time' => 1571190903 ],
[ 'id' => 3, 'title' => 'article 3', 'link' => 'http://article 3', 'user_id' => 1, 'votes' => 0, 'publish_time' => 1571190963 ],
[ 'id' => 4, 'title' => 'article 4', 'link' => 'http://article 4', 'user_id' => 1, 'votes' => 0, 'publish_time' => 1571191023 ],
[ 'id' => 5, 'title' => 'article 5', 'link' => 'http://article 5', 'user_id' => 1, 'votes' => 0, 'publish_time' => 1571191083 ]
複製代碼
同時在Redis創建起 articles_hit_rate
文章熱度 的有序列表(zset)ui
article 是文章id, score 爲 熱度評分this
測試zrevrangebyscore articles_hit_rate +inf -inf
根據分數倒序取值。結果;spa
local_redis:0>zrevrangebyscore articles_hit_rate +inf -inf
1) "5"
2) "4"
3) "3"
4) "2"
5) "1"
複製代碼
點贊、評論、瀏覽量的權重(常量),有個很好的計算方式: 發佈一天內,你認爲得到多少點贊👍的文章是優質文章/列表首頁展現多少條數據。( 好比 100 ) 權重常量:86400 / 100 = 864 ( 一天有86400秒 )
/**
* 點贊文章
* @param int $articleId 文章id
* @param int $userId 用戶id
* @param int $voteNum 點贊數
* @return bool
*/
public function voteArticle( int $articleId, int $userId, int $voteNum )
{
if ( $this->isVoted( $articleId, $userId ) ) return false; // 已投票,返回
$this->userVoted( $articleId, $userId );
$this->RedisUtil->hIncrBy( self::LIST_ARTICLE_PREFIXX . $articleId, 'votes', $voteNum ); // 更新文章點贊數
$this->RedisUtil->zinCrBy( self::LIST_ARTICLE_HIT_RATE, ( $voteNum * self::LIKE_HIT_RATE ), $articleId ); // 更新文章熱度
return true;
}
複製代碼
至於其餘維度,也能夠按照點贊方法以此類推... 固然爲了防止用戶對同一片文章進行屢次投票,還須要用Redis中無序列表set爲每篇文章創建已投票用戶。這個在代碼裏面有提現,這裏就不過多討論...