# 2.6 针对有序集合的命令

zset:有序集合(sorted set),也叫zset.和集合有一定的相似性,其中都不能出现重复的元素.在有序集合中,每个元素都会对一个一个score参数,以该参数作为排序的依据

## 2.6.1 读写有序集合的命令

* `ZADD`
  * 语法:`ZADD key [NX|XX] [CH] [INCR] score member [score member ...]`.其中:
    * NX:当key对应的zset不存在时才能添加元素
    * XX:当key对应的zset存在时才能添加元素
    * CH:不指定该选项时,则`ZADD`默认只返回新添加到zset中的元素数量;指定该选项时,则`ZADD`命令将返回被更新或添加的元素数量
    * INCR:当待插入的member不存在时,该参数无效;当待插入的member已存在时,则表示指定一个增量添加到已有member的分数上
    * score:用于描述元素的数值(权重)
    * memeber:元素的值
* `ZRANGE`
  * 语法:`ZRANGE key start stop [WITHSCORES]`.其中:
    * start:起始索引位置
    * stop:结束索引位置
    * WITHSCORES:同时展示元素所对应的score值
    * 功能:通过索引区间返回zset中指定区间内的成员.该命令以元素在zset中score的**升序**排序

例:

创建一个zset:

```
127.0.0.1:6379> ZADD emp 4.0 Mike 2.0 Peter 1.0 Tim 0.5 Johnson 0.0 David
(integer) 5
```

按元素在zset中的score升序排序,查询索引在\[0,2]范围内的元素:

```
127.0.0.1:6379> ZRANGE emp 0 2
1) "David"
2) "Johnson"
3) "Tim"
```

按元素在zset中的score升序排序,查询索引在\[0,2]范围内的元素及其权重:

```
127.0.0.1:6379> ZRANGE emp 0 2 WITHSCORES
1) "David"
2) "0"
3) "Johnson"
4) "0.5"
5) "Tim"
6) "1"
```

可以看到,按索引从zset中读取元素时,是按照元素在zset中的score升序排序的

* `ZREVRANGE`
  * 语法:`ZREVRANGE key start stop [WITHSCORES]`.其中:
    * start:起始索引位置
    * stop:结束索引位置
    * WITHSCORES:同时展示元素所对应的score值
    * 功能:通过索引区间返回zset中指定区间内的成员.该命令以元素在zset中score的**降序**排序

例:

查看zset中的所有元素及其对应的权重:

```
127.0.0.1:6379> ZRANGE emp 0 -1 WITHSCORES
 1) "David"
 2) "0"
 3) "Johnson"
 4) "0.5"
 5) "Tim"
 6) "1"
 7) "Peter"
 8) "2"
 9) "Mike"
10) "4"
```

按元素在zset中的score降序排序,查询索引在\[0,2]范围内的元素:

```
127.0.0.1:6379> ZREVRANGE emp 0 2
1) "Mike"
2) "Peter"
3) "Tim"
```

按元素在zset中的score降序排序,查询索引在\[0,2]范围内的元素及其权重:

```
127.0.0.1:6379> ZREVRANGE emp 0 2 WITHSCORES
1) "Mike"
2) "4"
3) "Peter"
4) "2"
5) "Tim"
6) "1"
```

* `ZRANGEBYSCORE`
  * 语法:`ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count]`.其中:
    * key:zset对应的key
    * min/max:类似查询条件.查询条件默认为:score ∈ \[min, max],可以使用`(min`的方式来调整区间的开闭
    * WITHSCORES:同上文
    * LIMIT:偏移量.offset表示偏移量,count表示取多少条
    * 功能:返回有序集中指定分数区间内的成员,分数从低到高排序

例:

使用`ZRANGEBYSCORE`命令查看zset中所有成员,score升序排序:

```
127.0.0.1:6379> ZRANGEBYSCORE emp -inf +inf WITHSCORES
 1) "David"
 2) "0"
 3) "Johnson"
 4) "0.5"
 5) "Tim"
 6) "1"
 7) "Peter"
 8) "2"
 9) "Mike"
10) "4"
```

使用`ZRANGEBYSCORE`命令查看zset中score ∈ \[0, 4]的成员及其权重:

```
127.0.0.1:6379> ZRANGEBYSCORE emp 0 4 WITHSCORES
 1) "David"
 2) "0"
 3) "Johnson"
 4) "0.5"
 5) "Tim"
 6) "1"
 7) "Peter"
 8) "2"
 9) "Mike"
10) "4"
```

使用`ZRANGEBYSCORE`命令查看zset中score ∈ (0, 4]的成员及其权重

```
127.0.0.1:6379> ZRANGEBYSCORE emp (0 4 WITHSCORES
1) "Johnson"
2) "0.5"
3) "Tim"
4) "1"
5) "Peter"
6) "2"
7) "Mike"
8) "4"
```

* `ZREVRANGEBYSCORE`
  * 语法:`ZREVRANGEBYSCORE key max min [WITHSCORES] [LIMIT offset count]`.其中:
    * key:zset对应的key
    * max/min:类似查询条件.查询条件默认为:score ∈ \[max, min],可以使用`(min`的方式来调整区间的开闭
    * WITHSCORES:同上文
    * LIMIT:偏移量.offset表示偏移量,count表示取多少条
    * 功能:返回有序集中指定分数区间内的成员,分数从高到低排序

例:

使用`ZREVRANGEBYSCORE`命令查看zset中所有成员,score降序排序:

```
127.0.0.1:6379> ZREVRANGEBYSCORE emp +inf -inf WITHSCORES
 1) "Mike"
 2) "4"
 3) "Peter"
 4) "2"
 5) "Tim"
 6) "1"
 7) "Johnson"
 8) "0.5"
 9) "David"
10) "0"
```

使用`ZREVRANGEBYSCORE`命令查看zset中score ∈ \[4, 0]的成员及其权重:

```
127.0.0.1:6379> ZREVRANGEBYSCORE emp 4 0 WITHSCORES
 1) "Mike"
 2) "4"
 3) "Peter"
 4) "2"
 5) "Tim"
 6) "1"
 7) "Johnson"
 8) "0.5"
 9) "David"
10) "0"
```

使用`ZREVRANGEBYSCORE`命令查看zset中score ∈ \[4, 0)的成员及其权重:

```
127.0.0.1:6379> ZREVRANGEBYSCORE emp 4 (0 WITHSCORES
1) "Mike"
2) "4"
3) "Peter"
4) "2"
5) "Tim"
6) "1"
7) "Johnson"
8) "0.5"
```

## 2.6.2 通过`ZINCRBY`命令修改元素的分值

* `ZINCRBY`
  * 语法:`ZINCRBY key increment member`.其中:
    * key:zset对应的键名
    * increment:score的变化量(可以为负数)
    * member:成员值
    * 功能:zset中对指定成员的分数加上增量increment.该命令的返回值为成员修改后的score

例:

查看有序集合中所有成员及其对应的score,按score升序排序:

```
127.0.0.1:6379> ZRANGEBYSCORE emp -inf +inf WITHSCORES
 1) "David"
 2) "0"
 3) "Johnson"
 4) "0.5"
 5) "Tim"
 6) "1"
 7) "Peter"
 8) "2"
 9) "Mike"
10) "4"
```

修改成员David的score,使该成员的score值减1:

```
127.0.0.1:6379> ZINCRBY emp -1 David
"-1"
```

对一个不存在于zset中的成员使用`ZINCRBY`命令:

```
127.0.0.1:6379> ZINCRBY emp -1 Kobe
"-1"
```

查看结果:

```
127.0.0.1:6379> ZRANGEBYSCORE emp -inf +inf WITHSCORES
 1) "David"
 2) "-1"
 3) "Kobe"
 4) "-1"
 5) "Johnson"
 6) "0.5"
 7) "Tim"
 8) "1"
 9) "Peter"
10) "2"
11) "Mike"
12) "4"
```

可以看到,对一个不存在于zset中的成员使用`ZINCRBY`命令后,该成员会被添加到zset中,并且该成员的score即为increment

## 2.6.3 用`ZSCORE`命令获取指定成员的分数

* `ZSCORE`
  * 语法:`ZSCORE key member`
  * 功能:查看key对应的set中,member的score.若key或member不存在则返回nil

例:

查看zset中的全部成员:

```
127.0.0.1:6379> ZRANGEBYSCORE emp -inf +inf WITHSCORES
 1) "David"
 2) "-1"
 3) "Kobe"
 4) "-1"
 5) "Johnson"
 6) "0.5"
 7) "Tim"
 8) "1"
 9) "Peter"
10) "2"
11) "Mike"
12) "4"
```

查看成员David的score:

```
127.0.0.1:6379> ZSCORE emp David
"-1"
```

查看zset中不存在的memeber:

```
127.0.0.1:6379> ZSCORE emp Allen
(nil)
```

对一个不存在的zset使用`ZSCORE`命令:

```
127.0.0.1:6379> ZSCORE notExist foo
(nil)
```

注意:`ZSCORE`命令只能返回1个元素的score

## 2.6.4 查看有序集合里的元素排名

* `ZRANK`
  * 语法:`ZRANK key member`
  * 功能:获取指定成员在zset中的索引,排序按score升序排序.若key或member不存在则返回nil
* `ZREVRANK`
  * 语法:`ZREVRANK key member`
  * 功能:获取指定成员在zset中的索引,排序按score降序排序.若key或member不存在则返回nil

例:

查看zset中所有成员及其对应score,按score升序排序:

```
127.0.0.1:6379> ZRANGEBYSCORE emp -inf +inf WITHSCORES
 1) "David"
 2) "-1"
 3) "Kobe"
 4) "-1"
 5) "Johnson"
 6) "0.5"
 7) "Tim"
 8) "1"
 9) "Peter"
10) "2"
11) "Mike"
12) "4"
```

查看David在zset中的索引,按score升序排序:

```
127.0.0.1:6379> ZRANK emp David
(integer) 0
```

查看zset中所有成员及其对应score,按score降序排序:

```
127.0.0.1:6379> ZREVRANGEBYSCORE emp +inf -inf WITHSCORES
 1) "Mike"
 2) "4"
 3) "Peter"
 4) "2"
 5) "Tim"
 6) "1"
 7) "Johnson"
 8) "0.5"
 9) "Kobe"
10) "-1"
11) "David"
12) "-1"
```

查看David在zset中的索引,按score降序排序:

```
127.0.0.1:6379> ZREVRANK emp David
(integer) 5
```

查看在zset中不存在的成员的索引:

```
127.0.0.1:6379> ZRANK emp Allen
(nil)
```

可以看到,当成员在zset中不存在时,返回值为nil

对一个不存在的zset查看其成员中的索引:

```
127.0.0.1:6379> ZRANK number one
(nil)
```

可以看到,当zset不存在时,返回值为nil

## 2.6.5 删除有序集合里的值

* `ZREM`
  * 语法:`ZREM key member [member ...]`
  * 功能:删除key指向的zset中的1个或多个成员.返回值为删除成员的数量

例:

查看zset中所有成员及其对应的score:

```
127.0.0.1:6379> ZRANGEBYSCORE emp -inf +inf WITHSCORES
 1) "David"
 2) "-1"
 3) "Kobe"
 4) "-1"
 5) "Johnson"
 6) "0.5"
 7) "Tim"
 8) "1"
 9) "Peter"
10) "2"
11) "Mike"
12) "4"
```

删除值为David的成员:

```
127.0.0.1:6379> ZREM emp David
(integer) 1
```

删除值为Kobe和值为Johnson的成员:

```
127.0.0.1:6379> ZREM emp Kobe Johnson
(integer) 2
```

查看zset中所有成员及其对应的score:

```
127.0.0.1:6379> ZRANGEBYSCORE emp -inf +inf WITHSCORES
1) "Tim"
2) "1"
3) "Peter"
4) "2"
5) "Mike"
6) "4"
```

删除一个zset中不存在的成员:

```
127.0.0.1:6379> ZREM emp Allen
(integer) 0
```

可以看到,对一个zset中不存在的成员执行删除操作,返回值为0

对一个不存在的zset执行`ZREM`命令:

```
127.0.0.1:6379> ZREM notExist one
(integer) 0
```

可以看到,对一个不存在的zset执行`ZREM`命令,返回值为0

* `ZREMRANGEBYRANK`
  * 语法:`ZREMRANGEBYRANK key start stop`
  * 功能:删除zset中索引在\[start, stop]范围内的成员,返回值为删除元素的个数.索引默认按score升序排序,但如果start和stop为负数,则表示要删除score较高的成员

例:

删除并创建一个zset:

```
127.0.0.1:6379> DEL emp
(integer) 1
127.0.0.1:6379> ZADD emp 0 David 0.5 Johnson 1 Tim 2 Peter 4 Mike
(integer) 5
```

查看zset中所有成员及其对应的score:

```
127.0.0.1:6379> ZRANGE emp 0 5 WITHSCORES
 1) "David"
 2) "0"
 3) "Johnson"
 4) "0.5"
 5) "Tim"
 6) "1"
 7) "Peter"
 8) "2"
 9) "Mike"
10) "4"
```

删除zset中索引在\[1,3]范围内的成员,按score升序排序:

```
127.0.0.1:6379> ZREMRANGEBYRANK emp 1 3
(integer) 3
```

查看删除后的zset:

```
127.0.0.1:6379> ZRANGE emp 0 5 WITHSCORES
1) "David"
2) "0"
3) "Mike"
4) "4"
```

注:没有`ZREVREMRANGEBYRANK`命令,但是可以通过负数索引的方式删除分数最高的几个成员

例:

删除并重新创建zset:

```
127.0.0.1:6379> DEL emp
(integer) 1
127.0.0.1:6379> ZADD emp 0 David 0.5 Johnson 1 Tim 2 Peter 4 Mike
(integer) 5
```

查看zset中所有成员及其对应的score:

```
127.0.0.1:6379> ZRANGE emp 0 5 WITHSCORES
 1) "David"
 2) "0"
 3) "Johnson"
 4) "0.5"
 5) "Tim"
 6) "1"
 7) "Peter"
 8) "2"
 9) "Mike"
10) "4"
```

按分数从高到低排序,删除分数排名第2到分数排名第4的3个成员:

```
127.0.0.1:6379> ZREMRANGEBYRANK emp -4 -2
(integer) 3
```

查看删除结果:

```
127.0.0.1:6379> ZRANGE emp 0 5 WITHSCORES
1) "David"
2) "0"
3) "Mike"
4) "4"
```

* `ZREMRANGEBYSCORE`
  * 语法:`ZREMRANGEBYSCORE key min max`
  * 功能:删除zset中score在\[min, max]范围内的成员,返回值为删除元素的个数

例:

删除并重新创建一个zset:

```
127.0.0.1:6379> DEL emp
(integer) 1
127.0.0.1:6379> ZADD emp 0 David 0.5 Johnson 1 Tim 2 Peter 4 Mike
(integer) 5
```

查看zset中所有成员及其对应的score:

```
127.0.0.1:6379> ZRANGE emp 0 5 WITHSCORES
 1) "David"
 2) "0"
 3) "Johnson"
 4) "0.5"
 5) "Tim"
 6) "1"
 7) "Peter"
 8) "2"
 9) "Mike"
10) "4"
```

删除score在\[0,1]范围内的成员:

```
127.0.0.1:6379> ZREMRANGEBYSCORE emp 0 1
(integer) 3
```

查看删除后的zset:

```
127.0.0.1:6379> ZRANGE emp 0 5 WITHSCORES
1) "Peter"
2) "2"
3) "Mike"
4) "4"
```

删除score在\[2,4)范围内的成员:

```
127.0.0.1:6379> ZREMRANGEBYSCORE emp 2 (4
(integer) 1
```

查看删除后的zset:

```
127.0.0.1:6379> ZRANGE emp 0 5 WITHSCORES
1) "Mike"
2) "4"
```

注:没有`ZREVREMRANGEBYSCORE`命令.因为无论是按score升序还是降序排序,最终要删除的都是给定score范围内的数据


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://redis.sai.show/di-2-zhang-shi-jian-redis-de-ji-ben-shu-ju-lei-xing/2.6-zhen-dui-you-xu-ji-he-de-ming-ling.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
