暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Redis每日一练(37):ZREVRANGEBYLEX、ZRANGEBYSCORE和ZREVRANGEBYSCORE命令

原创 AlbertS 2020-02-04
4052

版权声明: 转载请注明出处!本文采用 知识共享 署名-非商业性使用-禁止演绎 4.0 国际许可协议

前言

继续学习操作有序集合的命令,今天的这三个命令全都和范围有关,都是在有序集合中查询指定范围的元素,可以正序,也可以倒序,可以按字典序,也可以按照分数排序,具体细节我们一起来看一下吧。

这篇笔记中的3个命令分别是 ZREVRANGEBYLEX 、 ZRANGEBYSCORE 、 ZREVRANGEBYSCORE ,可以参考:

ZREVRANGEBYLEX

  • 最早出现版本:2.8.9
  • 时间复杂度:O(log(N)+M) (N是有序集合中的元素个数,M是返回结果中元素的个数)
  • 命令参数: ZREVRANGEBYLEX key max min [LIMIT offset count]
  • 操作类型:sorted sets
  • 官方文档

作用

这个命令和上一篇讲到的 ZRANGEBYLEX 基本一致,唯一的不同是按照字典降序排列的,命令中的 LEX 指的是 lexicographical ,也就是按照字典序排列,因为和 ZRANGEBYLEX 一样,我们来简单复习一下。

按照字典降序返回指定范围内的元素。当有序集合中所有元素的分数相同时返回指定字典序范围内的元素,当分数不同时结果未定义,返回结果不保证是惟一的。

字符串大小的比较,默认从小到大,类似于使用 memcmp 函数来比较,可以使用 LIMIT 选项,类似于 SQL 语句中的 limit 关键字用法,参数 count 也可以指定一个负数,表示从 offset 到最后的元素都作为结果返回。

指定范围的开始和结束时必须以 ( 或 [ 作为开头,( 表示开区间,[ 表示闭区间,+ 和 - 在这个命令中有着特殊含义,- 表示负无穷, + 表示正无穷, 如果有序集合中所有的元素分数都一样,那么 ZREVRANGEBYLEX zset - + 会返回所有的元素。

字符串会被当成二进制数组比较,所以在指定了ASCII字符集的状况下,对于全是ASCII范围内的字符可以正常比较,但是一些其他的字符集,比如utf8的字符比较起来可能会有问题,我们可以给字符分个段,前一段用来排序,后一段保存实际的元素内容来解决这个问题。

练习

向有序集合中添加多个分数相同的元素,然后使用 ZREVRANGEBYLEX 命令返回指定范围内的元素列表:

127.0.0.1:6379> DEL zset
(integer) 1
127.0.0.1:6379> ZADD zset 1 albert 1 bella 1 lili 1 tom
(integer) 4
127.0.0.1:6379> ZADD zset 1 zco 1 hoy 1 forge
(integer) 3
127.0.0.1:6379> ZRANGE zset 0 -1
1) "albert"
2) "bella"
3) "forge"
4) "hoy"
5) "lili"
6) "tom"
7) "zco"
127.0.0.1:6379> ZREVRANGE zset 0 -1
1) "zco"
2) "tom"
3) "lili"
4) "hoy"
5) "forge"
6) "bella"
7) "albert"
127.0.0.1:6379> ZREVRANGEBYLEX zset (l [b
1) "hoy"
2) "forge"
3) "bella"
127.0.0.1:6379> ZREVRANGEBYLEX zset (z [b LIMIT 1 2
1) "lili"
2) "hoy"
127.0.0.1:6379> ZREVRANGEBYLEX zset (z [b
1) "tom"
2) "lili"
3) "hoy"
4) "forge"
5) "bella"
127.0.0.1:6379>

ZRANGEBYSCORE

  • 最早出现版本:1.0.5
  • 时间复杂度:O(log(N)+M) (N是有序集合中的元素个数,M是返回结果中元素的个数)
  • 命令参数:ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count]
  • 操作类型:sorted sets
  • 官方文档

作用

按照分数从小到大排序,若分数相同则按照元素的字典序排列,返回指定分数段内的元素,这个排序无需额外操作,是有序列表本身内部实现的,也就是说本身就是有序的,只是从中截取一段数据来返回。

WITHSCORES 参数可以在每个元素的下面再显示对应的分数,这个参数是从2.0版本之后加上的, [LIMIT offset count] 参数的用法和 SQL 语句中的 limit 用法类似,offset 是从前面语句得到结果的偏移量,而 count 是从这个偏移量开始返回的元素个数,当 count 为负数时表示从指定的偏移量开始返回之后所有的元素。

这个命令在指定范围时与 ZRANGEBYLEX 有些区别,默认包含端点元素的,如果不想包含需要在前面加上 ( 符号,同时使用 -inf 表示无穷小,使用 +inf 表示无穷大。

命令返回指定范围内的元素,如果有 WITHSCORES 参数就连同分数一起返回了。

练习

向有序集合中添加多个元素,然后使用 ZRANGEBYSCORE 命令返回指定范围内的元素:

127.0.0.1:6379> DEL zset
(integer) 1
127.0.0.1:6379> ZADD zset 100 albert 92 tom 95 bella 95 lili
(integer) 4
127.0.0.1:6379> ZADD zset 92 adc 80 tank 70 sword
(integer) 3
127.0.0.1:6379> ZRANGE zset 0 -1 WITHSCORES
 1) "sword"
 2) "70"
 3) "tank"
 4) "80"
 5) "adc"
 6) "92"
 7) "tom"
 8) "92"
 9) "bella"
10) "95"
11) "lili"
12) "95"
13) "albert"
14) "100"
127.0.0.1:6379> ZRANGEBYSCORE zset 80 100 WITHSCORE
(error) ERR syntax error
127.0.0.1:6379> ZRANGEBYSCORE zset 80 100 WITHSCORES
 1) "tank"
 2) "80"
 3) "adc"
 4) "92"
 5) "tom"
 6) "92"
 7) "bella"
 8) "95"
 9) "lili"
10) "95"
11) "albert"
12) "100"
127.0.0.1:6379> ZRANGEBYSCORE zset (92 99 WITHSCORES
1) "bella"
2) "95"
3) "lili"
4) "95"
127.0.0.1:6379>

在上面有序集合的基础上,使用 [LIMIT offset count] 参数选项,特别想试一下 count 为0的情况:

127.0.0.1:6379> ZRANGE zset 0 -1 WITHSCORES
 1) "sword"
 2) "70"
 3) "tank"
 4) "80"
 5) "adc"
 6) "92"
 7) "tom"
 8) "92"
 9) "bella"
10) "95"
11) "lili"
12) "95"
13) "albert"
14) "100"
127.0.0.1:6379> ZRANGEBYSCORE zset 80 100 WITHSCORES LIMIT 1 2
1) "adc"
2) "92"
3) "tom"
4) "92"
127.0.0.1:6379> ZRANGEBYSCORE zset 80 100 WITHSCORES LIMIT 1 -10
 1) "adc"
 2) "92"
 3) "tom"
 4) "92"
 5) "bella"
 6) "95"
 7) "lili"
 8) "95"
 9) "albert"
10) "100"
127.0.0.1:6379> ZRANGEBYSCORE zset 80 100 WITHSCORES LIMIT 1 0
(empty list or set)
127.0.0.1:6379>

ZREVRANGEBYSCORE

  • 最早出现版本:2.2.0
  • 时间复杂度:O(log(N)+M) (N是有序集合中的元素个数,M是返回结果中元素的个数)
  • 命令参数:ZREVRANGEBYSCORE key max min [WITHSCORES] [LIMIT offset count]
  • 操作类型:sorted sets
  • 官方文档

作用

这个命令与 ZRANGEBYSCORE 命令几乎一模一样,唯一的不同就是这个命令是按照分数从大到小排列的,除此之外其他的功能与 ZRANGEBYSCORE 命令一致。

将元素按照分数从大到小排序,分数相同按照字典序降序排列,返回指定分数段内的元素,使用时注意参数 max 和 min 顺序。

练习

向有序集合中添加多个元素,然后使用 ZREVRANGEBYSCORE 命令返回指定范围内的元素:

127.0.0.1:6379> DEL zset
(integer) 1
127.0.0.1:6379> ZADD zset 100 albert 92 tom 95 bella 95 lili
(integer) 4
127.0.0.1:6379> ZADD zset 92 adc 80 tank 70 sword
(integer) 3
127.0.0.1:6379> ZREVRANGE zset 0 -1 WITHSCORES
 1) "albert"
 2) "100"
 3) "lili"
 4) "95"
 5) "bella"
 6) "95"
 7) "tom"
 8) "92"
 9) "adc"
10) "92"
11) "tank"
12) "80"
13) "sword"
14) "70"
127.0.0.1:6379> ZREVRANGEBYSCORE zset 100 80 WITHSCORES LIMIT 1 3
1) "lili"
2) "95"
3) "bella"
4) "95"
5) "tom"
6) "92"
127.0.0.1:6379>

总结

  1. ZREVRANGEBYLEX 命令可以将只包含相同分数的有序集合中元素,返回指定字典排序区间内的元素,字典排序按降序排序。
  2. ZRANGEBYSCORE 命令元素分数范围返回范围内的元素,并且按照从分数从小到大排序。
  3. ZREVRANGEBYSCORE 命令元素分数范围返回范围内的元素,并且按照从分数从大到小排序,与 ZRANGEBYSCORE 命令相反。

2020-1-16 17:00:43

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论