Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 8f4a000

Browse files
committed
feat: add redis-sorted-set-ranking-or-trending-list.md
利用 Redis Sorted Set 实现日/周/月topN榜单
1 parent 19d2ef8 commit 8f4a000

File tree

2 files changed

+147
-0
lines changed

2 files changed

+147
-0
lines changed

‎README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343

4444
### [Sorted Sets 有序集合](/docs/redis-sorted-set-introduction.md)
4545
- [社交网站通常会有粉丝关注的功能,用 Redis 怎么实现?](/docs/redis-sorted-set-sns-follow.md)
46+
- [每日、每周、每月积分排行榜功能该怎么实现?](/docs/redis-sorted-set-ranking-or-trending-list.md)
4647

4748
### [Hash 哈希](/docs/redis-hash-introduction.md)
4849
- [登录会话,用 Redis 该怎么做?](/docs/redis-hash-session-token.md)
Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
# 利用 Redis Sorted Set 实现日/周/月排行榜
2+
3+
## 代码实现
4+
| [Python](#Python-版本) | [Java](#Java-版本) |
5+
|---|---|
6+
7+
### Python 版本
8+
```python
9+
import datetime
10+
import time
11+
12+
from redis import Redis
13+
14+
15+
def get_day_rank_key():
16+
return 'rank:day:{}'.format(datetime.date.today().strftime('%Y%m%d'))
17+
18+
19+
def get_week_rank_key():
20+
return 'rank:week:{}{}'.format(datetime.date.today().strftime('%Y'), time.strftime("%W"))
21+
22+
23+
def get_month_rank_key():
24+
today = datetime.date.today()
25+
return 'rank:month:{}{}'.format(today.strftime('%Y'), today.strftime('%m'))
26+
27+
28+
class Ranking:
29+
def __init__(self, client: Redis):
30+
self.client = client
31+
32+
def incr(self, user, score=1):
33+
self.client.zincrby(get_day_rank_key(), score, user)
34+
self.client.zincrby(get_week_rank_key(), score, user)
35+
self.client.zincrby(get_month_rank_key(), score, user)
36+
37+
def get_today_top_n(self, n, with_scores=False):
38+
"""获取日榜单topN"""
39+
return self.client.zrevrange(get_day_rank_key(), 0, n - 1, withscores=with_scores)
40+
41+
def get_week_top_n(self, n, with_scores=False):
42+
"""获取周榜单topN"""
43+
return self.client.zrevrange(get_week_rank_key(), 0, n - 1, withscores=with_scores)
44+
45+
def get_month_top_n(self, n, with_scores=False):
46+
"""获取月榜单topN"""
47+
return self.client.zrevrange(get_month_rank_key(), 0, n - 1, withscores=with_scores)
48+
49+
50+
if __name__ == '__main__':
51+
redis = Redis(decode_responses=True)
52+
ranking = Ranking(redis)
53+
54+
ranking.incr('bingo', 5)
55+
ranking.incr('iris', 3)
56+
ranking.incr('lily', 4)
57+
ranking.incr('helen', 6)
58+
59+
print(ranking.get_today_top_n(n=2, with_scores=True)) # [('helen', 6.0), ('bingo', 5.0)]
60+
print(ranking.get_week_top_n(n=2, with_scores=True)) # [('helen', 6.0), ('bingo', 5.0)]
61+
print(ranking.get_month_top_n(n=3, with_scores=True)) # [('helen', 6.0), ('bingo', 5.0), ('lily', 4.0)]
62+
```
63+
64+
### Java 版本
65+
```java
66+
import redis.clients.jedis.Jedis;
67+
import redis.clients.jedis.Tuple;
68+
69+
import java.util.Calendar;
70+
import java.util.Set;
71+
72+
/**
73+
* @author bingoyang
74+
* @date 2019年9月7日
75+
*/
76+
public class Ranking {
77+
private Jedis client = new Jedis();
78+
private Calendar calendar = Calendar.getInstance();
79+
80+
public Ranking() {
81+
calendar.setFirstDayOfWeek(Calendar.MONDAY);
82+
}
83+
84+
private String getDayRankKey() {
85+
return String.format("rank:day:%s%s%s", calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DAY_OF_MONTH));
86+
}
87+
88+
private String getWeekRankKey() {
89+
return String.format("rank:week:%s%s", calendar.get(Calendar.YEAR), calendar.get(Calendar.WEEK_OF_YEAR));
90+
}
91+
92+
private String getMonthRankKey() {
93+
return String.format("rank:month:%s%s", calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH));
94+
}
95+
96+
public void incr(String user, double score) {
97+
client.zincrby(getDayRankKey(), score, user);
98+
client.zincrby(getWeekRankKey(), score, user);
99+
client.zincrby(getMonthRankKey(), score, user);
100+
}
101+
102+
/**
103+
* 获取日榜单topN
104+
*
105+
* @param n 前n位
106+
* @return 结果集合
107+
*/
108+
public Set<Tuple> getTodayTopNWithScores(long n) {
109+
return client.zrevrangeWithScores(getDayRankKey(), 0, n - 1);
110+
}
111+
112+
/**
113+
* 获取周榜单topN
114+
*
115+
* @param n 前n位
116+
* @return 结果集合
117+
*/
118+
public Set<Tuple> getWeekTopNWithScores(long n) {
119+
return client.zrevrangeWithScores(getWeekRankKey(), 0, n - 1);
120+
}
121+
122+
/**
123+
* 获取月榜单topN
124+
*
125+
* @param n 前n位
126+
* @return 结果集合
127+
*/
128+
public Set<Tuple> getMonthTopNWithScores(long n) {
129+
return client.zrevrangeWithScores(getMonthRankKey(), 0, n - 1);
130+
}
131+
132+
public static void main(String[] args) {
133+
Ranking ranking = new Ranking();
134+
135+
ranking.incr("bingo", 5);
136+
ranking.incr("iris", 3);
137+
ranking.incr("lily", 4);
138+
ranking.incr("helen", 6);
139+
140+
System.out.println(ranking.getTodayTopNWithScores(2)); // [[helen,6.0], [bingo,5.0]]
141+
System.out.println(ranking.getWeekTopNWithScores(2)); // [[helen,6.0], [bingo,5.0]]
142+
System.out.println(ranking.getMonthTopNWithScores(3)); // [[helen,6.0], [bingo,5.0], [lily,4.0]]
143+
144+
}
145+
}
146+
```

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /