详解redis的有序集合命令zrevrangebyscore在微博,新闻的使用

2022-04-25 09:22:59 浏览数 (1)

最近看redis相关的书籍,发现zrevrangebyscore在目前的业务中使用场景非常多,所以下面通过特殊的案例来分享一下zrevrangebyscore的使用。微博推荐,时事新闻,聊天记录拉取等应用中,数据都会按照时间排列,形成有序队列。下面我们会根据这类应用来讲解一下实际的案例使用。

Redis zrevrangebyscore 返回有序集中指定分数区间内的所有的成员。有序集成员按分数值递减(从大到小)的次序排列。具有相同分数值的成员按字典序的逆序(reverse lexicographical order )排列。

完整的使用示例

代码语言:javascript复制
zrevrangebyscore key max min [WITHSCORES] [LIMIT offset count]

参数说明

指令

是否必须

说明

ZREVRANGEBYSCORE

指令

key

有序集合键名称

max

最大分数值,可使用” inf”代替

min

最小分数值,可使用”-inf”代替

WITHSCORES

将成员分数一并返回

LIMIT

返回结果是否分页,指令中包含LIMIT后offset、count必须输入

offset

返回结果起始位置

count

返回结果数量

案例1:

微博的推荐,这个推荐一般都会基于一个用户来保存一个有序队列,然后用户拉取最新的推荐微博则基于当前的position进行拉取最新的数据,微博的数据我们设置成score的值是唯一并且自增的。

首先我们根据一个用户添加已有3条数据

代码语言:javascript复制
zadd weibo_recomend_1 2021081101 '{"title" : "recomend1","content":"xxx1", "time": 2021081101}'
zadd weibo_recomend_1 2021081102 '{"title" : "recomend2","content":"xxx2", "time": 2021081102}'
zadd weibo_recomend_1 2021081103 '{"title" : "recomend3","content":"xxx3", "time": 2021081103}'

假如用户打开微博访问了第一页,则会拉取第一页的数据。执行命令如下:

代码语言:javascript复制
zrevrangebyscore weibo_recomend_1  inf -inf LIMIT 0 2

返回数据如下

代码语言:javascript复制
1) "{"title" : "recomend3","content":"xxx3", "time": 2021081103}"
2) "{"title" : "recomend2","content":"xxx2", "time": 2021081102}"

当用户向下滑动,前端需要把第一次的最小一个position值(2021081102)传上来,redis执行命令如下:

代码语言:javascript复制
zrevrangebyscore weibo_recomend_1 2021081101 -inf LIMIT 0 2

返回结果如下

代码语言:javascript复制
1) "{"title" : "recomend1","content":"xxx1", "time": 2021081101}"

如果这个时候有插入新数据,插入新数据如下:

代码语言:javascript复制
zadd weibo_recomend_1 2021081104 '{"title" : "recomend4","content":"xxx4", "time": 2021081104}'

微博会提示有一条新微博消息,用户网上拉,前端会把当前最大的position值(2021081103)传上来,则执行命令如下

代码语言:javascript复制
zrevrangebyscore weibo_recomend_1  inf 2021081104 LIMIT 0 2

返回结果

代码语言:javascript复制
1) "{"title" : "recomend4","content":"xxx4", "time": 2021081104}"

案例2:

新闻推荐,我们如果使用redis做缓存拉取分页数据,有序集合是非常方便使用的,下面我们看下新闻的上拉和下拉的实现。

添加5条新闻

代码语言:javascript复制
zadd news 202110022301 '{"title" : "new1", "time": 202110022301}'
zadd news 202110022302 '{"title" : "new2", "time": 202110022302}'
zadd news 202110022303 '{"title" : "new3", "time": 202110022303}'
zadd news 202110022304 '{"title" : "new4", "time": 202110022304}'
zadd news 202110022304 '{"title" : "new4_1", "time": 202110022304}'
zadd news 202110022305 '{"title" : "new5", "time": 202110022305}'

当用户第一次打开新闻页面会执行如下操作

代码语言:javascript复制
ZREVRANGEBYSCORE news  inf -inf LIMIT 0 3

返回结果

代码语言:javascript复制
1) "{"title" : "new5", "time": 202110022305}"
2) "{"title" : "new4_1", "time": 202110022304}"
3) "{"title" : "new4", "time": 202110022304}"

基于第一页下拉,则需要把最小的position(202110022304)和这个position展示多少条数据的值提交给后端position_count(),则后端执行的命令如下:

代码语言:javascript复制
zrevrangebyscore news 202110022304 -inf LIMIT 2 3

返回结果

代码语言:javascript复制
1) "{"title" : "new3", "time": 202110022303}"
2) "{"title" : "new2", "time": 202110022302}"
3) "{"title" : "new1", "time": 202110022301}"

新增一条新的新闻

代码语言:javascript复制
zadd news 202110022306 '{"title" : "new6", "time": 202110022306}'

基于第一页上拉最新的数据score的数据有重复的,则需要前端传上次最后一个position和这个position对应的数据值,然后请求上报过来,则可以在程序中过滤掉展示过的数据。分页的条数不一样问题不是很大。当然如果我们保证新闻中的score是自增的并且是唯一的,则可以参照案例1的方式进行读取上拉,下拉的数据。

总结:

1:redis的zrevrangebyscore是最常用于分页使用的。

2:如果要使用zrevrangebyscore分页我们需要注意写入的score尽量保证是有序并且唯一的,这样我们才能方便的使用分页处理业务逻辑

0 人点赞