前文中我们已经介绍了Redis中有关于字符串的操作命令,以及一些对键值对操作的命令。在本文中,我们将介绍一种新类型的相关命令——列表(List)。列表是编程中非常常用的一种数据结构,通常有线性表(数组)与链表两种的实现。在Redis中,列表便是使用链表进行实现。由于篇幅的问题,列表的命令将分为两篇文章进行介绍。

LPUSH / RPUSH

LPUSHRPUSH命令用于将元素插入队列中,并在Redis 2.4以上版本支持一次将一个或多个元素插入队列中。两个命令的区别为LPUSH将新元素插入到队列的队首位置,而RPUSH命令将元素插入到队尾位置。命令执行后将返回插入元素后队列的长度。当键不存在,将创建一个空白的队列并执行插入操作;若键存在但不为队列,将返回错误。

LPUSH key element [element ...]
RPUSH key element [element ...]

当使用LPUSH插入多个元素时,将逐个将元素插入到队首。如插入abc后,队列中的顺序为cba

当使用RPUSH插入多个元素时,将逐个将元素插入到队尾。如插入abc后,队列中的顺序为abc

示例

使用LPUSH插入元素:

redis> LPUSH cards "0001" "0002"
(integer) 2
redis> LRANGE cards 0 -1
1) "0002"
2) "0001"
redis> LPUSH cards "0003"
(integer) 3
redis> LRANGE cards 0 -1
1) "0003"
2) "0002"
3) "0001"

使用RPUSH插入元素:

redis> RPUSH cards "0001" "0002"
(integer) 2
redis> LRANGE cards 0 -1
1) "0001"
2) "0002"
redis> LPUSH cards "0003"
(integer) 3
redis> LRANGE cards 0 -1
1) "0001"
2) "0002"
3) "0003"

已存在的键不为列表:

redis> SET greeting "hello world"
OK
redis> LPUSH greeting "test"
(error) WRONGTYPE Operation against a key holding the wrong kind of value

LPUSHX / RPUSHX

LPUSHX/RPUSHX命令与LPUSH/RPUSH类似,区别为它们仅在键已存在且为列表的情况下才执行插入的操作。当键不存在时,将无操作被执行;当键存在但不为列表类型时将返回错误。

LPUSHX key element [element ...]
RPUSHX key element [element ...]

LPUSHXRPUSHX命令在执行后,将返回列表的长度。若键不存在则返回0

示例

redis> LPUSHX cards "0002" "0003"
(integer) 0
redis> LPUSH cards "0001"
(integer) 1
redis> LPUSHX cards "0002" "0003"
(integer) 3
redis> LRANGE cards 0 -1
1) "0003"
2) "0002"
3) "0001"

LLEN

LLEN命令用于获取列表中存储的元素数量,若键不存在则当作空白的队列(即返回0)。当键存在但类型不为队列时将返回错误。

LLEN key

示例

redis> LLEN cards
(integer) 0
redis> LPUSH cards "0001" "0002"
(integer) 2
redis> LLEN cards
(integer) 2

LRANGE

LRANGE命令用于获取列表中由索引值startstop指定的范围内的元素,索引值从0开始(即0为列表中第一个元素),负数值表示相对于列表队尾的位置(如-1代表列表中最后一个元素,-2代表列表中倒数第二个元素)。LRANGE命令返回的元素将包含startstop范围内的所有元素,如使用LRANGE list 0 10将获取到索引为010的总共11个元素。

LRANGE key start stop

当索引超出列表边界时,将只返回范围内列表存在的元素,而不会返回错误。若偏移start大于队尾的位置,将返回空列表(即无元素);若偏移stop大于队尾的位置,将认为只获取到列表队尾的位置。

示例

redis> RPUSH cards "0001" "0002" "0003"
(integer) 3
redis> LRANGE cards 0 1
1) "0001"
2) "0002"
redis> LRANGE cards 0 -1
1) "0001"
2) "0002"
3) "0003"
# 起始位置大于实际位置
redis> LRANGE cards 4 5
(empty array)
# 结束位置大于实际位置
redis> LRANGE cards 0 5
1) "0001"
2) "0002"
3) "0003"

LPOP / RPOP

LPOP命令用于移除并返回队列中的第一个元素,当键不存在时返回nil。当列表中只有一个元素时,执行LPOP命令后键将被删除。

LPOP key

RPOP命令与LPOP相似,用于移除并返回列表中的最后一个元素。

RPOP key

示例

redis> LPOP cards
(nil)
redis> LPUSH cards "0001" "0002" "0003"
(integer) 3
redis> RPOP cards
"0001"
redis> LPOP cards
"0003"
redis> RPOP cards
"0002"
redis> LPOP cards
(nil)

LINDEX

LINDEX命令用于获取列表中指定索引的元素,当索引超出列表范围时返回nil。索引的值从0开始,即0代表列表中的第一个元素,1代表列表中的第二个元素。当索引的值为负数时,表示相对于列表队尾的位置,如-1代表列表中最后一个元素,-2代表列表中倒数第二个元素。

LINDEX key index

示例

redis> RPUSH cards "0001" "0002" "0003"
(integer) 3
redis> LINDEX cards 0
"0001"
redis> LINDEX cards 1
"0002"
redis> LINDEX cards 3
(nil)
redis> LINDEX cards -1
"0003"
redis> LINDEX cards -2
"0002"

LSET

LSET命令用于设置列表中指定位置的元素,当索引不在列表的范围内时将返回错误。与LINDEX相同,索引从0开始,且负数值代表相对于队尾的位置。

LSET key index element

示例

redis> RPUSH cards "0001" "0002" "0003"
(integer) 3
redis> LSET cards 0 "0004"
OK
redis> LSET cards -2 "0005"
OK
redis> LRANGE cards 0 -1
1) "0004"
2) "0005"
3) "0003"

LINSERT

LINSERT命令用于将元素插入到指定元素pivot之前或之后的位置,并返回插入元素后列表的长度。当元素pivot不存在时,将返回-1。若键不存在将视作其为一个空的列表,不执行任何操作。

LINSERT key BEFORE|AFTER pivot element

示例

# 不存在的键
redis> LINSERT cards AFTER "0002" "0004"
(integer) 0
redis> LRANGE cards 0 -1
(empty array)
redis> RPUSH cards "0001" "0002" "0003"
(integer) 3
# 插入到元素之前
redis> LINSERT cards BEFORE "0002" "0004"
(integer) 4
# 插入到元素之后
redis> LINSERT cards AFTER "0002" "0005"
(integer) 5
# 不存在的元素
redis> LINSERT cards AFTER "0000" "0006"
(integer) -1
redis> LRANGE cards 0 -1
1) "0001"
2) "0004"
3) "0002"
4) "0005"
5) "0003"

LREM

LREM命令用于移除队列中指定数量与参数element值相同的元素,并返回实际移除的元素数量。若键不存在,则是作为一个空列表,执行后将返回0(即无符合的元素被删除)。

LREM key count element

LREM命令执行的操作受到count参数影响,不同的count值执行的操作为:

  • count > 0时,将从队首开始移除对应数量相同的元素;
  • count < 0时,将从队尾开始移除对应数量相同的元素;
  • count = 0,将移除列表中所有相同的元素。

示例

redis> LREM mykey 1 "hello"
(integer) 0
redis> RPUSH mykey "hello" "redis" "hello" "redis" "hello"
(integer) 5
# 删除不存在的值
redis> LREM mykey 1 "world"
(integer) 0
# 删除存在的值
redis> LREM mykey 1 "hello"
(integer) 1
redis> LREM mykey 0 "hello"
(integer) 2

count大于0的情况:

redis> RPUSH mykey "hello" "redis" "hello" "redis" "hello"
(integer) 5
redis> LREM mykey 2 "hello"
(integer) 2
redis> LRANGE mykey 0 -1
1) "redis"
2) "redis"
3) "hello"

count小于0的情况:

redis> RPUSH mykey "hello" "redis" "hello" "redis" "hello"
(integer) 5
redis> LREM mykey -2 "hello"
(integer) 2
redis> LRANGE mykey 0 -1
1) "hello"
2) "redis"
3) "redis"

结束语

本文中已经介绍了Redis中列表操作的一部分命令,在后续的文章中将继续介绍剩下的诸如LPOSLTRIM等命令。

参考文献