25-命令
3.6.2 命令
1.增加元素
ZADD key score member [score member …]
ZADD 命令用来向有序集合中加入一个元素和该元素的分数,如果该元素已经存在则会用新的分数替换原有的分数。 ZADD 命令的返回值是新加入到集合中的元素个数(不包含之前已经存在的元素)。
假设我们用有序集合模拟计分板,现在要记录Tom、Peter和David三名运动员的分数(分别是89分、67分和100分):
redis>ZADD scoreboard 89 Tom 67 Peter 100 David
(integer) 3
这时我们发现Peter的分数录入有误,实际的分数应该是76分,可以用 ZADD 命令修改Peter的分数:
redis>ZADD scoreboard 76 Peter
(integer) 0
分数不仅可以是整数,还支持双精度浮点数:
redis>ZADD testboard 17E+307 a
(integer) 1
redis>ZADD testboard 1.5 b
(integer) 1
redis>ZADD testboard +inf c
(integer) 1
redis>ZADD testboard -inf d
(integer) 1
其中 +inf 和 -inf 分别表示正无穷和负无穷。
2.获得元素的分数
ZSCORE key member
示例如下:
redis>ZSCORE scoreboard Tom
"89"
3.获得排名在某个范围的元素列表
ZRANGE key start stop [WITHSCORES]
ZREVRANGE key start stop [WITHSCORES]
ZRANGE 命令会按照元素分数从小到大的顺序返回索引从 start 到 stop 之间的所有元素(包含两端的元素)。 ZRANGE 命令与 LRANGE 命令十分相似,如索引都是从0开始,负数代表从后向前查找(−1表示最后一个元素)。就像这样:
redis>ZRANGE scoreboard 0 2
1) "Peter"
2) "Tom"
3) "David"
redis>ZRANGE scoreboard 1 -1
1) "Tom"
2) "David"
如果需要同时获得元素的分数的话可以在 ZRANGE 命令的尾部加上 WITHSCORES 参数,这时返回的数据格式就从“元素1, 元素2, …, 元素n”变为了“元素1, 分数1, 元素2, 分数2, …, 元素n, 分数n”,例如:
redis>ZRANGE scoreboard 0 -1 WITHSCORES
1) "Peter"
2) "76"
3) "Tom"
4) "89"
5) "David"
6) "100"
ZRANGE 命令的时间复杂度为O(log n+m)(其中n为有序集合的基数,m为返回的元素个数)。
如果两个元素的分数相同,Redis会按照字典顺序(即"0" < "9" < "A" < "Z" < "a" < "z"这样的顺序)来进行排列。再进一步,如果元素的值是中文怎么处理呢?答案是取决于中文的编码方式,如使用UTF-8编码:
redis>ZADD chineseName 0 马华 0 刘墉 0 司马光 0 赵哲
(integer) 4
redis>ZRANGE chineseName 0 -1
1) "\xe5\x88\x98\xe5\xa2\x89"
2) "\xe5\x8f\xb8\xe9\xa9\xac\xe5\x85\x89"
3) "\xe8\xb5\xb5\xe5\x93\xb2"
4) "\xe9\xa9\xac\xe5\x8d\x8e"
可见此时Redis依然按照字典顺序排列这些元素。
ZREVRANGE 命令和 ZRANGE 的唯一不同在于 ZREVRANGE 命令是按照元素分数从大到小的顺序给出结果的。
4.获得指定分数范围的元素
ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count]
ZRANGEBYSCORE 命令参数虽然多,但是都很好理解。该命令按照元素分数从小到大的顺序返回分数在 min 和 max 之间(包含 min 和 max )的元素:
redis>ZRANGEBYSCORE scoreboard 80 100
1) "Tom"
2) "David"
如果希望分数范围不包含端点值,可以在分数前加上“(”符号。例如,希望返回”80分到100分的数据,可以含80分,但不包含100分,则稍微修改一下上面的命令即可:
redis>ZRANGEBYSCORE scoreboard 80 (100
1) "Tom"
min 和 max 还支持无穷大,同 ZADD 命令一样, -inf 和 +inf 分别表示负无穷和正无穷。比如你希望得到所有分数高于80分(不包含80分)的人的名单,但你却不知道最高分是多少(虽然有些背离现实,但是为了叙述方便,这里假设可以获得的分数是无上限的),这时就可以用上 +inf 了:
redis>ZRANGEBYSCORE scoreboard (80 +inf
1) "Tom"
2) "David"
WITHSCORES 参数的用法与 ZRANGE 命令一样,不再赘述。
了解SQL语句的读者对 LIMIT offset count 应该很熟悉,在本命令中 LIMIT offset count 与 SQL 中的用法基本相同,即在获得的元素列表的基础上向后偏移 offset 个元素,并且只获取前 count 个元素。为了便于演示,我们先向 scoreboard 键中再增加些元素:
redis>ZADD scoreboard 56 Jerry 92 Wendy 67 Yvonne
(integer) 3
现在 scoreboard 键中的所有元素为:
redis>ZRANGE scoreboard 0 -1 WITHSCORES
1) "Jerry"
2) "56"
3) "Yvonne"
4) "67"
5) "Peter"
6) "76"
7) "Tom"
8) "89"
9) "Wendy"
10) "92"
11) "David"
12) "100"
想获得分数高于60分的从第二个人开始的3个人:
redis>ZRANGEBYSCORE scoreboard 60 +inf LIMIT 1 3
1) "Peter"
2) "Tom"
3) "Wendy"
那么,如果想获取分数低于或等于 100 分的前 3 个人怎么办呢?这时可以借助 ZREVRANGEBYSCORE 命令实现。对照前文提到的 ZRANGE 命令和 ZREVRANGE 命令之间的关系,相信读者很容易能明白 ZREVRANGEBYSCORE 命令的功能。需要注意的是 ZREVRANGEBYSCORE 命令不仅是按照元素分数从大往小的顺序给出结果的,而且它的 min 和 max 参数的顺序和 ZRANGEBYSCORE 命令是相反的。就像这样:
redis>ZREVRANGEBYSCORE scoreboard 100 0 LIMIT 0 3
1) "David"
2) "Wendy"
3) "Tom"
5.增加某个元素的分数
ZINCRBY key increment member
ZINCRBY 命令可以增加一个元素的分数,返回值是更改后的分数。例如,想给Jerry加4分:
redis>ZINCRBY scoreboard 4 Jerry
"60"
increment 也可以是个负数表示减分,例如,给Jerry减4分:
redis>ZINCRBY scoreboard -4 Jerry
"56"
如果指定的元素不存在,Redis 在执行命令前会先建立它并将它的分数赋为 0 再执行操作。