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