This article is the beginning of Redis series, full of code practice, you can follow me if you like
scenario
Content sites such as blogs, forums and so on let quality content get enough exposure, is an important way to improve the attractiveness of the site. Today we are going to take a closer look at the scenario where the popular articles list often occupies the C-bit of the site.
First the product manager comes to talk to you.
Just kidding, multi-dimensional comprehensive sort is often encountered ~ how to do?
The core idea
We introduce the concept of heat, which is actually a popularity score for an article. We’re counting post times, likes, comments, views… The formula translates to heat, and then you sort by it
practice
The articles are sorted in reverse chronological order, so we can understand a score that decays over time, using Unix time here. Likes, comments, views… Times its own weight (constant), plus the date of publication equals the article rating
Time decay score
First, prepare article data: ID :1 is the earliest to publish, ID :5 is the latest
[ '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 ]
Copy the code
Also set up ordered list of articles_hit_rate article popularity (zset) in Redis
Article ID, score
Test zRevRangeByScore articles_hit_rate + INF – INF in reverse order byscore Results;
local_redis:0>zrevrangebyscore articles_hit_rate +inf -inf
1) "5"
2) "4"
3) "3"
4) "2"
5) "1"
Copy the code
Zrevrangebyscore document
Thumb up 👍
The weight of likes, comments and page views (constant), there is a good way to calculate: within one day of publication, how many likes do you think 👍 is a good article/list of the first page of the number of data. Weight constant: 86400/100 = 864 (86400 seconds in a day)
/** ** @param int$articleIdArticle id * @param int$userIdUser ID * @param int$voteNumLikes * @return bool
*/
public function voteArticle( int $articleId, int $userId, int $voteNum )
{
if ( $this->isVoted( $articleId.$userId))return false; // Voted, return$this->userVoted( $articleId.$userId );
$this->RedisUtil->hIncrBy( self::LIST_ARTICLE_PREFIXX . $articleId.'votes'.$voteNum); // Update the number of likes$this->RedisUtil->zinCrBy( self::LIST_ARTICLE_HIT_RATE, ( $voteNum * self::LIKE_HIT_RATE ), $articleId); // Update the article popularityreturn true;
}
Copy the code
As for other dimensions, the same can be said for liking… Of course, in order to prevent users from voting for the same article more than once, it is also necessary to use the unordered list set in Redis to establish voting users for each article. There is a withdrawal in the code, but we won’t discuss it much here…
The source code
Source code link