likes
comments
collection
share

Redis之Sorted Set数据类型API及应用场景解析

作者站长头像
站长
· 阅读数 65

「这是我参与2022首次更文挑战的第26天,活动详情查看:2022首次更文挑战


  • j3_liuliang
  • Redis常用API即应用场景系列(sorted set),如果觉得有用可以关注博主,不定时更新哦!

相关文章导航

  1. 超详细Redis之Key操作API,什么?看不懂!你来锤我
  2. Redis之String超详细API使用及应用场景介绍
  3. SCAN及相关SSCAN,HSCAN和ZSCAN命令解析
  4. 什么?Redis的List类型不会用,看我这个超详细API使用及应用场景
  5. Redis之Hash超详细API使用及应用场景介绍,不看亏了!
  6. Redis之Set集合数据类型API使用及图文并茂应用场景,不看血亏!
  7. Redis之Sorted Set数据类型API及应用场景解析

一、有序集合(sorted set)

有序集合和集合类似,只是说它是有序的,和无序集合的主要区别在于每一个元素除了值之外,它还会多一个分数。

  1. 分数是一个浮点数,在 Java 中是使用双精度表示的,根据分数, Redis 就可以支持对分数从小到大或者从大到小的排序
  2. 和无序集合一样,对于每一个元素都是唯一的 ,但是对于不同元素而言,它的分数可以一样
  3. 元素也是 String 数据类型,也是一种基于 hash 的存储结构。
  4. 集合是通过哈希表实现的,所以添加、删除、 查找的复杂度都是 0(1)
  5. 集合中最大的成员数为 2的32次方减 1 ( 40 多亿个成员)

1.1 ZADD(zadd)

向有序集合添加一个或多个成员,或者更新已存在成员的分数

Redis Zadd 命令用于将一个或多个成员元素及其分数值加入到有序集当中。

如果某个成员已经是有序集的成员,那么更新这个成员的分数值,并通过重新插入这个成员元素,来保证该成员在正确的位置上。

分数值可以是整数值或双精度浮点数。

如果有序集合 key 不存在,则创建一个空的有序集并执行 ZADD 操作。

当 key 存在但不是有序集类型时,返回一个错误。

注意: 在 Redis 2.4 版本以前, ZADD 每次只能添加一个元素。

语法

127.0.0.1:6379> ZADD key [NX|XX] [CH] [INCR] score member [score member ...]
  • XX: 仅仅更新存在的成员,不添加新成员。
  • NX: 不更新存在的成员。只添加新成员。
  • CH: 修改返回值为发生变化的成员总数,原始是返回新添加成员的总数 (CH 是 changed 的意思)。更改的元素是新添加的成员,已经存在的成员更新分数。 所以在命令中指定的成员有相同的分数将不被计算在内。注:在通常情况下,ZADD返回值只计算新添加成员的数量。
  • INCR: 当ZADD指定这个选项时,成员的操作就等同ZINCRBY命令,对成员的分数进行递增操作。

分数可以精确的表示的整数的范围:

Redis 有序集合的分数使用双精度64位浮点数。我们支持所有的架构,这表示为一个IEEE 754 floating point number,它能包括的整数范围是-(2^53)+(2^53)。或者说是-9007199254740992 到 9007199254740992。更大的整数在内部用指数形式表示,所以,如果为分数设置一个非常大的整数,你得到的是一个近似的十进制数。

可以版本:>= 1.2.0

返回值:被成功添加的新成员的数量,不包括那些被更新的、已经存在的成员;成员的新分数(双精度的浮点型数字)字符串。

案例

127.0.0.1:6379> flushall
OK
127.0.0.1:6379> zadd myzadd 98 j3_liuliang 92 xiaowang	#添加数据
(integer) 2
127.0.0.1:6379> zrange myzadd 0 -1	#返回集合数据,不带 score 这个值
1) "xiaowang"
2) "j3_liuliang"
127.0.0.1:6379> zrange myzadd 0 -1 withscores #返回集合数据,带 score 这个值
1) "xiaowang"
2) "92"
3) "j3_liuliang"
4) "98"
127.0.0.1:6379> 

1.2 ZRANGE(zrange)

通过索引区间返回有序集合成指定区间内的成员

返回存储在有序集合key中的指定范围的元素。 返回的元素可以认为是按得分从最低到最高排列。 如果得分相同,将按字典排序。

当你需要元素从最高分到最低分排列时,请参阅ZREVRANGE(相同的得分将使用字典倒序排序)。

参数startstop都是基于零的索引,即0是第一个元素,1是第二个元素,以此类推。 它们也可以是负数,表示从有序集合的末尾的偏移量,其中-1是有序集合的最后一个元素,-2是倒数第二个元素,等等。

startstop都是全包含的区间,因此例如ZRANGE myzset 0 1将会返回有序集合的第一个和第二个元素。

超出范围的索引不会产生错误。 如果start参数的值大于有序集合中的最大索引,或者start > stop,将会返回一个空列表。 如果stop的值大于有序集合的末尾,Redis会将其视为有序集合的最后一个元素。

可以传递WITHSCORES选项,以便将元素的分数与元素一起返回。这样,返回的列表将包含value1,score1,...,valueN,scoreN,而不是value1,...,valueN。 客户端类库可以自由地返回更合适的数据类型(建议:具有值和得分的数组或记录)。

语法

127.0.0.1:6379> ZRANGE key start stop [WITHSCORES]

可以版本:>= 1.2.0

返回值:给定范围内的元素列表(如果指定了WITHSCORES选项,将同时返回它们的得分)。

案例

127.0.0.1:6379> flushall
OK
127.0.0.1:6379> zadd myzadd 98 j3_liuliang 92 xiaowang	#添加数据
(integer) 2
127.0.0.1:6379> zrange myzadd 0 -1	#返回指定区间数据
1) "xiaowang"
2) "j3_liuliang"
127.0.0.1:6379> zrange myzadd 0 -1 withscores	#返回带 score 得数据
1) "xiaowang"
2) "92"
3) "j3_liuliang"
4) "98"
127.0.0.1:6379> zrange myzadd 0 -2 withscores
1) "xiaowang"
2) "92"
127.0.0.1:6379> zrange myzadd 0 -3 withscores	#指定区间没有数据就返回空
(empty list or set)
127.0.0.1:6379> 

1.3 ZRANK(zrank)

返回有序集合中指定成员的排名(索引)

返回有序集key中成员member的排名。其中有序集成员按score值递增(从小到大)顺序排列。排名以0为底,也就是说,score值最小的成员排名为0。

使用ZREVRANK命令可以获得成员按score值递减(从大到小)排列的排名。

语法

127.0.0.1:6379> ZRANK key member

可以版本:>= 2.0.0

返回值:如果成员是有序集 key 的成员,返回 member 的排名。 如果成员不是有序集 key 的成员,返回 nil 。

案例

127.0.0.1:6379> flushall
OK
127.0.0.1:6379> zadd myzadd 98 j3_liuliang 92 xiaowang 59 laoli	#添加数据
(integer) 3
127.0.0.1:6379> zrange myzadd 0 -1 withscores	#返回所有数据,由小到大
1) "laoli"
2) "59"
3) "xiaowang"
4) "92"
5) "j3_liuliang"
6) "98"
127.0.0.1:6379> zrank myzadd laoli	#由小到大,返回 0 说明倒数第一
(integer) 0
127.0.0.1:6379> 

1.4 ZREM(zrem)

移除有序集合中的一个或多个成员

Redis Zrem 命令用于移除有序集中的一个或多个成员,不存在的成员将被忽略。

当 key 存在但不是有序集类型时,返回一个错误。

注意: 在 Redis 2.4 版本以前, ZREM 每次只能删除一个元素。

语法

127.0.0.1:6379> ZREM key member [member ...]

可以版本:>= 1.2.0

返回值:被成功移除的成员的数量,不包括被忽略的成员。

案例

127.0.0.1:6379> zrange myzadd 0 -1 withscores	#查看数据
1) "laoli"
2) "59"
3) "xiaowang"
4) "92"
5) "j3_liuliang"
6) "98"
127.0.0.1:6379> zrem myzadd laoli			#把第 0 位数据删除
(integer) 1
127.0.0.1:6379> zrange myzadd 0 -1 withscores	#查看数据
1) "xiaowang"
2) "92"
3) "j3_liuliang"
4) "98"
127.0.0.1:6379> 

1.5 ZCARD(zcard)

获取有序集合的成员数

Redis Zcard 命令用于计算集合中元素的数量。

语法

127.0.0.1:6379> ZCARD KEY_NAME

可以版本:>= 1.2.0

返回值:当 key 存在且是有序集类型时,返回有序集的基数。 当 key 不存在时,返回 0 。

案例

127.0.0.1:6379> zrange myzadd 0 -1 withscores	#添加数据
1) "xiaowang"
2) "92"
3) "j3_liuliang"
4) "98"
127.0.0.1:6379> zcard myzadd	#查看key中元素得个数
(integer) 2
127.0.0.1:6379> 

1.6 ZCOUNT(zcount)

计算在有序集合中指定区间分数的成员数

Redis Zcount 命令用于计算有序集合中指定分数区间的成员数量。

语法

127.0.0.1:6379> ZCOUNT key min max

可以版本:>= 2.0.0

返回值:分数值在 min 和 max 之间的成员的数量。

案例

127.0.0.1:6379> flushall
OK
127.0.0.1:6379> zadd myzset 99 j3_liuliang 89 xiaowng 75 laoli 57 xiaoming	#添加数据
(integer) 4
127.0.0.1:6379> zcount myzset 100 80	
(integer) 0
127.0.0.1:6379> zcount myzset 80 100	#分数再100 到 80分之间得人数
(integer) 2
127.0.0.1:6379> zcount myzset 80 10
(integer) 0
127.0.0.1:6379> 

1.7 ZINCRBY(zincrby)

有序集合中对指定成员的分数加上增量 increment

Redis Zincrby 命令对有序集合中指定成员的分数加上增量 increment

可以通过传递一个负数值 increment ,让分数减去相应的值,比如 ZINCRBY key -5 member ,就是让 member 的 score 值减去 5 。

当 key 不存在,或分数不是 key 的成员时, ZINCRBY key increment member 等同于 ZADD key increment member 。

当 key 不是有序集类型时,返回一个错误。

分数值可以是整数值或双精度浮点数。

语法

127.0.0.1:6379> ZINCRBY key increment member

可以版本:>= 1.2.0

返回值:member 成员的新分数值,以字符串形式表示。

案例

127.0.0.1:6379> zrange myzset 0 -1 withscores	#查看zset集合数据
1) "xiaoming"
2) "57"
3) "laoli"
4) "75"
5) "xiaowng"
6) "89"
7) "j3_liuliang"
8) "99"
127.0.0.1:6379> zincrby myzset 30 xiaoming		#给倒数第一的分数加 30 
"87"
127.0.0.1:6379> zrange myzset 0 -1 withscores	#查看zset集合数据
1) "laoli"
2) "75"
3) "xiaoming"
4) "87"
5) "xiaowng"
6) "89"
7) "j3_liuliang"
8) "99"
127.0.0.1:6379> zincrby myzset -11 j3_liuliang	#给第一得分数减 11
"88"
127.0.0.1:6379> zrange myzset 0 -1 withscores	#查看zset集合数据
1) "laoli"
2) "75"
3) "xiaoming"
4) "87"
5) "j3_liuliang"
6) "88"
7) "xiaowng"
8) "89"
127.0.0.1:6379> 

1.8 ZINTERSTORE(zinterstore)

计算给定的一个或多个有序集的交集并将结果集存储在新的有序集合 key 中

计算给定的numkeys个有序集合的交集,并且把结果放到destination中。 在给定要计算的key和其它参数之前,必须先给定key个数(numberkeys)。

默认情况下,结果中一个元素的分数是有序集合中该元素分数之和,前提是该元素在这些有序集合中都存在。因为交集要求其成员必须是给定的每个有序集合中的成员,结果集中的每个元素的分数和输入的有序集合个数相等。

对于WEIGHTS和AGGREGATE参数的描述,参见命令ZUNIONSTORE

如果destination存在,就把它覆盖。

语法

127.0.0.1:6379> ZINTERSTORE destination numkeys key [key ...] [WEIGHTS weight [weight ...]] [AGGREGATE SUM|MIN|MAX]

可以版本:>= 2.0.0

返回值:保存到目标结果集的的成员数量。

案例

127.0.0.1:6379> flushall
OK
127.0.0.1:6379> zadd myzset01 18 j3_liuliang 25 xiaoming				#设置集合数据
(integer) 2
127.0.0.1:6379> zadd myzset02 18 j3_liuliang 25 xiaomwang 23 laoli		
(integer) 3
127.0.0.1:6379> zinterstore myzset03 2 myzset01 myzset02	#求交集,将结果放入指定集合中
(integer) 1
127.0.0.1:6379> zrange myzset03 0 -1 withscores	#查看结果集合数据
1) "j3_liuliang"
2) "36"
127.0.0.1:6379> 

1.9 ZLEXCOUNT(zlexcount)

在有序集合中计算指定字典区间内成员数量

Redis Zlexcount 命令在计算有序集合中指定字典区间内成员数量。

语法

127.0.0.1:6379> ZLEXCOUNT KEY MIN MAX
  • key:有序集合键名称
  • min:在有序集合中分数排名较小的成员
  • max:在有序集合中分数排名较大的成员

提示:

  • 成员名称前需要加 [ 符号作为开头, [ 符号与成员之间不能有空格
  • 可以使用 -+ 表示得分最小值和最大值
  • minmax 不能反, max 放前面 min放后面会导致返回结果为0
  • 计算成员之间的成员数量时,参数 minmax 的位置也计算在内。
  • minmax 参数的含义与 zrangebylex 命令中所描述的相同

可以版本:>= 2.8.9

返回值:有序集合中成员名称 min 和 max 之间的成员数量; Integer类型。

案例

127.0.0.1:6379> flushall
OK
127.0.0.1:6379> zadd myzset01 0 a 1 b 2 c 3 d 4 e 5 f	#设置有序集合数据
(integer) 6
127.0.0.1:6379> zadd myzset01 6 g 7 h 8 i 
(integer) 3
127.0.0.1:6379> zlexcount myzset01 - +	#记录最小值和最大值之间得数据个数
(integer) 9
127.0.0.1:6379> zlexcount myzset01 [c [f	#记录指定区间数据个数
(integer) 4
127.0.0.1:6379> 

1.10 ZPOPMAX(zpopmax)

删除并返回有序集合key中的最多count个具有最高得分的成员。

如未指定,count的默认值为1。指定一个大于有序集合的基数的count不会产生错误。 当返回多个元素时候,得分最高的元素将是第一个元素,然后是分数较低的元素。

语法

127.0.0.1:6379> ZPOPMAX key [count]

可以版本:>=5.0.0

返回值:弹出的元素和分数列表。

案例

127.0.0.1:6379> flushall
OK
127.0.0.1:6379> zadd myset 98 j3_liuliang 78 xiaowang 66 laoli 23 laozhang	#添加数据
(integer) 4
127.0.0.1:6379> zpopmax myset 2		#弹出两个分数最大得成员
1) "j3_liuliang"
2) "98"
3) "xiaowang"
4) "78"
127.0.0.1:6379> zrange myset 0 -1 withscores	#查看数据
1) "laozhang"
2) "23"
3) "laoli"
4) "66"
127.0.0.1:6379> 

1.11 ZPOPMIN(zpopmin)

删除并返回有序集合key中的最多count个具有最低得分的成员。

如未指定,count的默认值为1。指定一个大于有序集合的基数的count不会产生错误。 当返回多个元素时候,得分最低的元素将是第一个元素,然后是分数较高的元素。

语法

127.0.0.1:6379> ZPOPMIN key [count]

可以版本:>=5.0.0

返回值:弹出的元素和分数列表。

案例

127.0.0.1:6379> flushall
OK
127.0.0.1:6379> zadd myset 98 j3_liuliang 78 xiaowang 66 laoli 23 laozhang	#添加数据
(integer) 4
127.0.0.1:6379> zpopmin myset 2					#弹出两个分数最小得成员
1) "laozhang"
2) "23"
3) "laoli"
4) "66"
127.0.0.1:6379> zrange myset 0 -1 withscores	#查看数据
1) "xiaowang"
2) "78"
3) "j3_liuliang"
4) "98"
127.0.0.1:6379> 

1.12 ZRANGEBYLEX(zrangebylex)

移除有序集合中给定的字典区间的所有成员

ZRANGEBYLEX 返回指定成员区间内的成员,按成员字典正序排序, 分数必须相同。

在某些业务场景中,需要对一个字符串数组按名称的字典顺序进行排序时,可以使用Redis中SortSet这种数据结构来处理。

语法

127.0.0.1:6379> ZRANGEBYLEX key min max [LIMIT offset count]
  • MIN:字典中排序位置较小的成员,必须以"["开头,或者以"("开头,可使用"-"代替
  • MAX:字典中排序位置较大的成员,必须以"["开头,或者以"("开头,可使用"+"代替
  • LIMIT:返回结果是否分页,指令中包含LIMIT后offset、count必须输入
  • OFFSET:返回结果起始位置
  • COUNT:返回结果数量

提示:

  • 分数必须相同! 如果有序集合中的成员分数有不一致的,返回的结果就不准。
  • 成员字符串作为二进制数组的字节数进行比较。
  • 默认是以ASCII字符集的顺序进行排列。如果成员字符串包含utf-8这类字符集的内容,就会影响返回结果,所以建议不要使用。
  • 默认情况下, “max” 和 “min” 参数前必须加 “[” 符号作为开头。”[” 符号与成员之间不能有空格, 返回成员结果集会包含参数 “min” 和 “max” 。
  • “max” 和 “min” 参数前可以加 “(“ 符号作为开头表示小于, “(“ 符号与成员之间不能有空格。返回成员结果集不会包含 “max” 和 “min” 成员。
  • 可以使用 “-“ 和 “+” 表示得分最小值和最大值
  • “min” 和 “max” 不能反, “max” 放前面 “min”放后面会导致返回结果为空
  • 与ZRANGEBYLEX获取顺序相反的指令是ZREVRANGEBYLEX
  • 源码中采用C语言中memcmp()函数, 从字符的第0位到最后一位进行排序,如果前面部分相同,那么较长的字符串比较短的字符串排序靠后。

可以版本:>= 2.8.9

返回值:指定成员范围的元素列表。

案例

不要在分数不一致的SortSet集合中去使用 ZRANGEBYLEX 指令,因为获取的结果并不准确。

127.0.0.1:6379> flushall
OK
127.0.0.1:6379> zadd myzset 1 sdf 1 sdf 1 dfgdf 1 sdf 1 yhjk 1 yj 1 gh	#添加数据
(integer) 5
127.0.0.1:6379> zadd myzset 1 sde 1 fgnfg
(integer) 2
127.0.0.1:6379> zrange myzset 0 -1	#查看数据
1) "dfgdf"
2) "fgnfg"
3) "gh"
4) "sde"
5) "sdf"
6) "yhjk"
7) "yj"
127.0.0.1:6379> zrangebylex myzset - +	#查看范围内得所有数据
1) "dfgdf"
2) "fgnfg"
3) "gh"
4) "sde"
5) "sdf"
6) "yhjk"
7) "yj"
127.0.0.1:6379> zrangebylex myzset [gh [yj	#查看范围内得所有数据
1) "gh"
2) "sde"
3) "sdf"
4) "yhjk"
5) "yj"
127.0.0.1:6379> zrange myzset 0 -1	#查看数据
1) "dfgdf"
2) "fgnfg"
3) "gh"
4) "sde"
5) "sdf"
6) "yhjk"
7) "yj"
127.0.0.1:6379> 

1.13 ZRANGEBYSCORE(zrangebyscore)

返回有序集中指定分数区间内的成员,分数从高到低排序

语法

127.0.0.1:6379> ZREVRANGEBYSCORE key max min [WITHSCORES] [LIMIT offset count]

具有相同分数的元素按字典序排列(这个根据redis对有序集合实现的情况而定,并不需要进一步计算)。

可选的LIMIT参数指定返回结果的数量及区间(类似SQL中SELECT LIMIT offset, count)。注意,如果offset太大,定位offset就可能遍历整个有序集合,这会增加O(N)的复杂度。

可选参数WITHSCORES会返回元素和其分数,而不只是元素。这个选项在redis2.0之后的版本都可用。

区间及无限

min和max可以是-inf和+inf,这样一来,你就可以在不知道有序集的最低和最高score值的情况下,使用ZRANGEBYSCORE这类命令。

默认情况下,区间的取值使用闭区间(小于等于或大于等于),你也可以通过给参数前增加(符号来使用可选的开区间(小于或大于)。

举个例子:

ZRANGEBYSCORE zset (1 5

返回所有符合条件1 < score <= 5的成员;

ZRANGEBYSCORE zset (5 (10

返回所有符合条件5 < score < 10 的成员。

可以版本:>=1.0.5

返回值:指定分数范围的元素列表(也可以返回他们的分数)。

案例

127.0.0.1:6379> flushall
OK
127.0.0.1:6379> zadd myzset 1 one 2 two 3 three	#添加数据
(integer) 3
127.0.0.1:6379> zrangebyscore myzset -inf +inf	#获取所有从最小到最大范围内数据
1) "one"
2) "two"
3) "three"
127.0.0.1:6379> zrangebyscore myzset 1 (2	#获取 1<= x <2 得数据
1) "one"
127.0.0.1:6379> zrangebyscore myzset 2 3	#获取 2= x <=3 得数据
1) "two"
2) "three"
127.0.0.1:6379> 

1.14 ZREMRANGEBYLEX(zremrangebylex)

移除有序集合中给定的字典区间的所有成员

ZREMRANGEBYLEX 删除名称按字典由低到高排序成员之间所有成员。

不要在成员分数不同的有序集合中使用此命令, 因为它是基于分数一致的有序集合设计的,如果使用,会导致删除的结果不正确。

待删除的有序集合中,分数最好相同,否则删除结果会不正常。

语法

127.0.0.1:6379> ZREMRANGEBYLEX key min max
  • key:有序集合键名称
  • min:字典中排序位置较小的成员,必须以"["开头,或者以"("开头,可使用"-"代替
  • max:字典中排序位置较大的成员,必须以"["开头,或者以"("开头,可使用"+"代替

提示:

  • 有序集合中分数必须相同! 如果有序集合中的成员分数有不一致的,结果就不准。
  • 成员顺序是按成员字符串作为二进制数组的字节数进行比较。
  • 默认是以ASCII字符集的顺序进行排列。如果成员字符串包含utf-8这类字符集的内容,就会影响返回结果,所以建议不要使用。
  • 源码中采用C语言中memcmp()函数, 从字符的第0位到最后一位进行排序,如果前面部分相同,那么较长的字符串比较短的字符串排序靠后。
  • 默认情况下, “max” 和 “min” 参数前必须加 “[” 符号作为开头。”[” 符号与成员之间不能有空格, 返回成员结果集会包含参数 “max”和 “min”
  • “max” 和 “min” 参数前可以加 “(“ 符号作为开头表示小于, “(“ 符号与成员之间不能有空格。返回成员结果集不会包含 “max” 和 “min” 成员。
  • 可以使用 “-“ 和 “+” 表示得分最小值和最大值
  • “max”和 “min” 不能反, “max” 放后面 “min”放前面会删除不了元素

可以版本:>= 2.8.9

返回值:被成功移除的成员的数量,不包括被忽略的成员。

案例

27.0.0.1:6379> flushall
OK
127.0.0.1:6379> zadd myzset 0 a 0 b 0 c 0 d 0 e 0 dsfg 0 sdg	#添加数据
(integer) 7
127.0.0.1:6379> zadd myzset 0 dfg 0 dfs
(integer) 2
127.0.0.1:6379> zrange myzset 0 -1	#查看元素,不带分数
1) "a"
2) "b"
3) "c"
4) "d"
5) "dfg"
6) "dfs"
7) "dsfg"
8) "e"
9) "sdg"
127.0.0.1:6379> zremrangebylex myzset [a [c	#移除指定区间数据
(integer) 3
127.0.0.1:6379> zrangebylex myzset - +	#查看数据
1) "d"
2) "dfg"
3) "dfs"
4) "dsfg"
5) "e"
6) "sdg"
127.0.0.1:6379> zremrangebylex myzset [e (sdg	#移除指定区间数据
(integer) 1
127.0.0.1:6379> zrangebylex myzset - +	#查看数据
1) "d"
2) "dfg"
3) "dfs"
4) "dsfg"
5) "sdg"
127.0.0.1:6379> 

1.15 ZREMRANGEBYRANK(zremrangebyrank)

移除有序集合中给定的排名区间的所有成员

移除有序集key中,指定排名(rank)区间内的所有成员。下标参数start和stop都以0为底,0处是分数最小的那个元素。这些索引也可是负数,表示位移从最高分处开始数。例如,-1是分数最高的元素,-2是分数第二高的,依次类推。

语法

127.0.0.1:6379> ZREMRANGEBYRANK key start stop

可以版本:>= 2.0.0

返回值:被移除成员的数量。

案例

127.0.0.1:6379> flushall
OK
127.0.0.1:6379> zadd chengji 99 j3_liuliang 85 xiaoming 56 laowang	#设置数据
(integer) 3
127.0.0.1:6379> zrange chengji 0 -1 withscores	#查看数据
1) "laowang"
2) "56"
3) "xiaoming"
4) "85"
5) "j3_liuliang"
6) "99"
127.0.0.1:6379> zremrangebyrank chengji 0 1		#移除指定区间数据
(integer) 2
127.0.0.1:6379> zrange chengji 0 -1 withscores	#查看数据
1) "j3_liuliang"
2) "99"
127.0.0.1:6379> 

1.16 ZREMRANGEBYSCORE(zremrangebyscore)

移除有序集合中给定的分数区间的所有成员

移除有序集key中,所有score值介于min和max之间(包括等于min或max)的成员。 自版本2.1.6开始,score值等于min或max的成员也可以不包括在内,语法请参见ZRANGEBYSCORE命令。

语法

127.0.0.1:6379> ZREVRANGEBYSCORE key max min [WITHSCORES] [LIMIT offset count]

可以版本:>= 2.2.0

返回值:删除的元素的个数。

案例

127.0.0.1:6379> flushall							#清空数据库
OK
127.0.0.1:6379> zadd myzset 1 one 2 two 3 three		#添加数据
(integer) 3
127.0.0.1:6379> zremrangebyscore myzset 1 2			#随机移除分数再1到2闭区间得数值
(integer) 2
127.0.0.1:6379> zrange myzset 0 -1 withscores		#遍历集合
1) "three"
2) "3"
127.0.0.1:6379> 

1.17 ZREVRANGE(zrevrange)

返回有序集中指定区间内的成员,通过索引,分数从高到底

Redis Zrevrange 命令返回有序集中,指定区间内的成员。

其中成员的位置按分数值递减(从大到小)来排列。

具有相同分数值的成员按字典序的逆序(reverse lexicographical order)排列。

除了成员按分数值递减的次序排列这一点外, ZREVRANGE 命令的其他方面和 ZRANGE 命令一样。

语法

127.0.0.1:6379> ZREVRANGE key start stop [WITHSCORES]

可以版本:>= 1.2.0

返回值:指定区间内,带有分数值(可选)的有序集成员的列表。

案例

127.0.0.1:6379> flushall
OK
127.0.0.1:6379> zadd chengji 98 j3_liuliang 89 xiaohong 67 huazai 79 axiang
(integer) 4
127.0.0.1:6379> zrange chengji 0 -1 withscores			#由小到大
1) "huazai"
2) "67"
3) "axiang"
4) "79"
5) "xiaohong"
6) "89"
7) "j3_liuliang"
8) "98"
127.0.0.1:6379> zrevrange chengji 0 -1 withscores		#由大到小
1) "j3_liuliang"
2) "98"
3) "xiaohong"
4) "89"
5) "axiang"
6) "79"
7) "huazai"
8) "67"
127.0.0.1:6379> 

1.18 ZREVRANGEBYLEX(zrevrangebylex)

移除有序集合中给定的字典区间的所有成员

ZREMRANGEBYLEX 删除名称按字典由低到高排序成员之间所有成员。 不要在成员分数不同的有序集合中使用此命令, 因为它是基于分数一致的有序集合设计的,如果使用,会导致删除的结果不正确。 待删除的有序集合中,分数最好相同,否则删除结果会不正常。

语法

127.0.0.1:6379> ZREMRANGEBYLEX key min max

可以版本:>= 2.8.9

返回值:被成功移除的成员的数量,不包括被忽略的成员。

案例

127.0.0.1:6379> flushall
OK
127.0.0.1:6379> zadd myzset 0 a 0 b 0 c 0 d 0 e 0 f 0 g 0 h 0 i 0 j 0 k 0 m 0 b	#添加数据
(integer) 12
127.0.0.1:6379> zrange myzset 0 -1				#遍历集合数据
 1) "a"
 2) "b"
 3) "c"
 4) "d"
 5) "e"
 6) "f"
 7) "g"
 8) "h"
 9) "i"
10) "j"
11) "k"
12) "m"
127.0.0.1:6379> zremrangebylex myzset [c [h		#移除指定区间数据
(integer) 6
127.0.0.1:6379> zrange myzset 0 -1
1) "a"
2) "b"
3) "i"
4) "j"
5) "k"
6) "m"
127.0.0.1:6379> 

1.19 ZREVRANGEBYSCORE(zrevrangebyscore)

返回有序集中指定分数区间内的成员,分数从高到低排序

Redis Zrevrangebyscore 返回有序集中指定分数区间内的所有的成员。有序集成员按分数值递减(从大到小)的次序排列。

具有相同分数值的成员按字典序的逆序(reverse lexicographical order )排列。

除了成员按分数值递减的次序排列这一点外, ZREVRANGEBYSCORE 命令的其他方面和 ZRANGEBYSCORE命令一样。

语法

127.0.0.1:6379> ZREVRANGEBYSCORE key max min [WITHSCORES] [LIMIT offset count]

可以版本:>= 2.2.0

返回值:指定区间内,带有分数值(可选)的有序集成员的列表。

案例

127.0.0.1:6379> flushall
OK
127.0.0.1:6379> zadd myzset 200 a 156 b 789 c 2 d 18 e 90 f	#添加元素
(integer) 6
127.0.0.1:6379> zrevrangebyscore myzset +inf -inf			#由大到小排列数据
1) "c"
2) "a"
3) "b"
4) "f"
5) "e"
6) "d"
127.0.0.1:6379> zrevrangebyscore myzset 200 0				#返回200 到 0 之间得数据
1) "a"
2) "b"
3) "f"
4) "e"
5) "d"
127.0.0.1:6379> 

1.20 ZREVRANK(zrevrank)

返回有序集合中指定成员的排名,有序集成员按分数值递减(从大到小)排序

Redis Zrevrank 命令返回有序集中成员的排名。其中有序集成员按分数值递减(从大到小)排序。

排名以 0 为底,也就是说, 分数值最大的成员排名为 0 。

使用 ZRANK 命令可以获得成员按分数值递增(从小到大)排列的排名。

语法

127.0.0.1:6379> ZREVRANK key member

可以版本:>= 2.2.0

返回值:如果成员是有序集 key 的成员,返回成员的排名。 如果成员不是有序集 key 的成员,返回 nil 。

案例

127.0.0.1:6379> flushall
OK
127.0.0.1:6379> zadd gongzi 20000 j3_liuliang 15000 laoli 10000 ahua 16000 xiaoming	#添加数据
(integer) 4
127.0.0.1:6379> zrevrank gongzi j3_liuliang		#工资最高
(integer) 0
127.0.0.1:6379> zrevrank gongzi ahua			#工资第四
(integer) 3
127.0.0.1:6379> 

1.21 ZSCAN(zscan)

迭代有序集合中的元素(包括元素成员和元素分值)

Redis Zscan 命令用于迭代有序集合中的元素(包括元素成员和元素分值)

语法

127.0.0.1:6379> redis 127.0.0.1:6379> ZSCAN key cursor [MATCH pattern] [COUNT count]

可以版本:>= 2.8.0

返回值:返回的每个元素都是一个有序集合元素,一个有序集合元素由一个成员(member)和一个分值(score)组成。

案例

可以参考:SCAN及相关SSCAN,HSCAN和ZSCAN命令解析

1.22 ZSCORE(zscore)

返回有序集中,成员的分数值

返回有序集key中,成员member的score值。

如果member元素不是有序集key的成员,或key不存在,返回nil。

语法

127.0.0.1:6379> ZSCORE key member

可以版本:>= 1.2.0

返回值:成员的分数值,以字符串形式表示。

案例

127.0.0.1:6379> flushall
OK
127.0.0.1:6379> zadd gongzi 20000 j3_liuliang 15000 laoli 10000 ahua 16000 xiaoming	#添加数据
(integer) 4
127.0.0.1:6379> zscore gongzi j3_liuliang		#返回j3_liuliang得工资(字符串)
"20000"
127.0.0.1:6379> 

1.23 ZUNIONSTORE(zunionstore)

计算给定的一个或多个有序集的并集,并存储在新的 key 中

计算给定的numkeys个有序集合的并集,并且把结果放到destination中。在给定要计算的key和其它参数之前,必须先给定key个数(numberkeys)。 默认情况下,结果集中某个成员的score值是所有给定集下该成员score值之和。

使用WEIGHTS选项,你可以为每个给定的有序集指定一个乘法因子,意思就是,每个给定有序集的所有成员的score值在传递给聚合函数之前都要先乘以该因子。如果WEIGHTS没有给定,默认就是1。

使用AGGREGATE选项,你可以指定并集的结果集的聚合方式。默认使用的参数SUM,可以将所有集合中某个成员的score值之和作为结果集中该成员的score值。如果使用参数MIN或者MAX,结果集就是所有集合中元素最小或最大的元素。

如果key destination存在,就被覆盖。

语法

ZUNIONSTORE destination numkeys key [key ...] [WEIGHTS weight [weight ...]] [AGGREGATE SUM|MIN|MAX]

可以版本:>= 2.0.0

返回值:保存到 destination 的结果集的成员数量。

案例

127.0.0.1:6379> flushall
OK
127.0.0.1:6379> zadd gongzi01 20000 j3_liuliang 15000 laoli 10000 ahua 16000 xiaoming		#添加数据
(integer) 4
127.0.0.1:6379> zadd gongzi02 40000 a 30000 b 20000 c 32000 d
(integer) 4
127.0.0.1:6379> zrange gongzi01 0 -1 withscores			#查看集合数据
1) "ahua"
2) "10000"
3) "laoli"
4) "15000"
5) "xiaoming"
6) "16000"
7) "j3_liuliang"
8) "20000"
127.0.0.1:6379> zrange gongzi02 0 -1 withscores
1) "c"
2) "20000"
3) "b"
4) "30000"
5) "d"
6) "32000"
7) "a"
8) "40000"
127.0.0.1:6379> zunionstore gongzi 2 gongzi01 gongzi02 weights 2 1	#将多个集合数据合并到一个集合中,并且第一个集合得分数乘余2 第二																		个乘余1之后再放入目标集合
(integer) 8
127.0.0.1:6379> zrange gongzi 0 -1 withscores	#查看目标集合数据
 1) "ahua"
 2) "20000"
 3) "c"
 4) "20000"
 5) "b"
 6) "30000"
 7) "laoli"
 8) "30000"
 9) "d"
10) "32000"
11) "xiaoming"
12) "32000"
13) "a"
14) "40000"
15) "j3_liuliang"
16) "40000"
127.0.0.1:6379> 

1.24 BZPOPMIN(bzpopmin)

BZPOPMIN 是有序集合命令 ZPOPMIN带有阻塞功能的版本。

在参数中的所有有序集合均为空的情况下,阻塞连接。参数中包含多个有序集合时,按照参数中key的顺序,返回第一个非空key中分数最小的成员和对应的分数

参数 timeout 可以理解为客户端被阻塞的最大秒数值,0 表示永久阻塞。

详细说明请参照BLPOP 说明文档,BZPOPMIN适用有序集合类型的key,BLPOP适用列表类型的key,除此之外,两条命令无其他差别。

语法

可以版本:>=5.0.0

返回值:

当有序集合无结果返回且超时设置过期时返回 nil

返回三元素multi-bulk结果,第一元素key名称,第二元素成员名称,第三元素分数

案例

127.0.0.1:6379> flushall
OK
127.0.0.1:6379> zadd myzset 100 a 45 b 95 c 58 d	#添加数据
(integer) 4
127.0.0.1:6379> zrange myzset 0 -1 withscores		#遍历数据
1) "b"
2) "45"
3) "d"
4) "58"
5) "c"
6) "95"
7) "a"
8) "100"
127.0.0.1:6379> bzpopmin myzset myzset01 0		#阻塞式将最小分数数据弹出并添加到目标集合中
1) "myzset"
2) "b"
3) "45"

1.25 BZPOPMAX(bzpopmax)

BZPOPMAX 是有序集合命令 ZPOPMAX带有阻塞功能的版本。

在参数中的所有有序集合均为空的情况下,阻塞连接。参数中包含多个有序集合时,按照参数中key的顺序,返回第一个非空key中分数最大的成员和对应的分数

参数 timeout 可以理解为客户端被阻塞的最大秒数值,0 表示永久阻塞。

详细说明请参照BZPOPMIN 说明文档BZPOPMAX返回非空有序集合 key中分数最大的成员,而BZPOPMIN返回该key中分数最小的成员,除此之外,两条命令无其他差别。

语法

可以版本:>=5.0.0

返回值:

当有序集合无结果返回且超时设置过期时返回 nil

返回三元素multi-bulk结果,第一元素key名称,第二元素成员名称,第三元素分数

案例

127.0.0.1:6379> flushall
OK
127.0.0.1:6379> zadd myzset 100 a 45 b 95 c 58 d
(integer) 4
127.0.0.1:6379> zrange myzset
(error) ERR wrong number of arguments for 'zrange' command
127.0.0.1:6379> zrange myzset 0 -1 withscores
1) "b"
2) "45"
3) "d"
4) "58"
5) "c"
6) "95"
7) "a"
8) "100"
127.0.0.1:6379> bzpopmax myzset myzset01 0		#阻塞式将最大分数数据弹出并添加到目标集合中
1) "myzset"
2) "a"
3) "100"
127.0.0.1:6379> 

二、应用场景

2.1 排行榜

​ 相信大家对排行榜都不陌生吧!玩过游戏的肯定都知道游戏中的积分排行榜,购物的销量排行榜,微博的热搜排行榜等这些在某个时间点跟新数据的排行变化都可以用Redis的有序集合做。但对于一些实时性比较强的,需要及时更新数据,可以利用redis的有序队列实现;

如图CSDN的周排行榜(不知道博主我什么时候可以上榜,嘻嘻):

Redis之Sorted Set数据类型API及应用场景解析

既然看了这个图,那我简单的来写个案例:

127.0.0.1:6379> flushall
OK
127.0.0.1:6379> zadd rankingList 830 yigechunvzuo 564 leesinDong 556 aobing 543 beilianhua 538 east 529 woshizengxiaogao
(integer) 6															#博客排名排行榜
127.0.0.1:6379> zrevrange rankingList 0 -1 withscores				#排行榜列表
 1) "yigechunvzuo"
 2) "830"
 3) "leesinDong"
 4) "564"
 5) "aobing"
 6) "556"
 7) "beilianhua"
 8) "543"
 9) "east"
10) "538"
11) "woshizengxiaogao"
12) "529"
127.0.0.1:6379> zadd rankingList 600 j3_liuliang 					#现在j3_liuliang这个博主加入到排行榜中
(integer) 1
127.0.0.1:6379> zrevrange rankingList 0 -1 withscores				#排行版变化,j3_liuliang周排行二,嘻嘻!
 1) "yigechunvzuo"
 2) "830"
 3) "j3_liuliang"
 4) "600"
 5) "leesinDong"
 6) "564"
 7) "aobing"
 8) "556"
 9) "beilianhua"
10) "543"
11) "east"
12) "538"
13) "woshizengxiaogao"
14) "529"
127.0.0.1:6379> 

转载自:https://juejin.cn/post/7064743011728490526
评论
请登录