The leaderboard feature is a very common requirement. Using the attributes of an ordered collection in Redis to achieve a leaderboard is a good and fast choice.
The general leaderboard is effective, such as the "User standings". If the results are not always in line with the overall list, it may be the top of a few old users, for new users, it is really frustrating.
First of all, a "Today's standings," The collation is today users add more points from the less.
Then, when users add points, they operate an ordered set of points added on the day of recording.
Assuming today is April 01, 2015, the user with the UID of 1 has added 5 points for an operation.
The Redis command is as follows:
ZINCRBY rank:20150401 5 1
Let's say that several other users have added points as well:
ZINCRBY rank:20150401 1 2ZINCRBY rank:20150401 10 3
Take a look at the data in the Ordered collection rank:20150401 (the Withscores parameter can be supplied with the score for the element):
ZRANGE rank:20150401 0 -1 withscores
1) "2"2) "1"3) "1"4) "5"5) "3"6) "10"
Get TOP10 by score from high to Low:
ZREVRANGE rank:20150401 0 9 withscores
1) "3"2) "10"3) "1"4) "5"5) "2"6) "1"
Because there are only three elements, the data is queried.
If you record the day's leaderboard every day, then the list of other tricks is simple.
such as "Yesterday's standings":
ZREVRANGE rank:20150331 0 9 withscores
Achieve "Last week's standings" by using a combination of multiple days of integration:
7 rank:20150323 rank:20150324 rank:20150325 rank:20150326 rank:20150327 rank:20150328 rank:20150329 WEIGHTS 1 1 1 1 1 1 1
This merges the 7-day integration record into the ordered set Rank:last_week. Weight factor WEIGHTS If not given, the default is 1. In order not to hide the details, deliberately written.
So the query for last week's standings TOP10 is:
ZREVRANGE rank:last_week 0 9 withscores
Monthly standings, quarterly charts, annual charts and so on.
<?phpclass ranks{const PREFIX = ' Zhengban ';p rotected $redis = ';/* Initialize */public function __construct (Redis $redis) {$th Is->redis = $redis;} /* Added to leaderboard */public function addscores ($gameid, $score) {$key = self::P refix. Date (' Ymd '); return $this->redis-> Zincrby ($key, $score, $gameid);} /* Get leaderboard data for a particular day returns a one-dimensional array, key is Gameid,value is score */public function getonedayrankings ($date, $start, $end) {$key = self:: PREFIX. $date; return $this->redis->zrevrange ($key, $start, $end, true);} /* Get leaderboard for days data */public function getmultidaysrankings ($dates, $start, $end) {$outKey = Null;foreach ($dates as $v) {$keys [] = Self::P refix. $v;} $weights = Array_fill (0, Count ($keys), 1); $this->redis->zunion ($outKey, $keys, $weights); $this->redis->zunion ($outKey, $keys); return $this->redis->zrevrange ($outKey, $start, $end, True);}} $host = "192.168.1.114"; $port = 6379; $pwd = "123456"; $redis = new Redis (); if ($redis->connect ($host, $port) = = False) { Exit (' {' REsult ":"-1 "} '); Connection failed}/* auth password */if ($redis->auth ($pwd) = = False) {exit (' {' result ': '-2 '} '); Authentication failed} $Ranks = new ranks ($redis);//$Ranks->addscores (12,1); er = $Ranks->getmultidaysrankings (Array ( 20151021,20151022,20151020), 0,9); Var_dump (er);
Results
Array ten = String ' One ' (length=2) 1 = String ' (length=2) 3 = String ' 6 ' (length=1) 2 = String ' 5 ' (length=1) 5 = String ' 4 ' (length=1) 4 = = String ' 3 ' (length=1) [ =] string ' 2 ' (length =1) + = String ' 1 ' (length=1) 1 = String ' 1 ' (length=1)
Using Redis to achieve leaderboard functionality