【问题标题】:Delete all entries in a Redis list删除 Redis 列表中的所有条目
【发布时间】:2012-04-07 08:40:24
【问题描述】:

假设您在 Redis 中有一个 LIST 数据类型。你如何删除它的所有条目?我已经试过了:

LTRIM key 0 0
LTRIM key -1 0

这两个都离开了第一个元素。这将留下所有元素:

LTRIM key 0 -1

我没有看到完全清空列表的单独命令。

【问题讨论】:

  • @DavidJames:考虑一下“foo”的另一种拼写方式。我遵循 Redis 自己的文档中使用的约定:redis.io/commands
  • 是的,在redis中,所有的数据结构都是key。这并不意味着'key'在示例中很有用。我认为恰恰相反。使用mylist 会让你的问题更清楚。例如,redis.io/commands/ltrim 写道:LTRIM mylist 1 -1。您引用的页面是命令reference,不应被视为制作良好示例的“惯例”。

标签: list redis


【解决方案1】:

删除密钥,这将清除所有项目。根本没有列表类似于没有任何项目。当你尝试访问一个不存在的键时,Redis 不会抛出任何异常。

DEL key

这是一些控制台日志。

redis>键* (空列表或集合) redis> LPUSH 命名 John (整数) 1 redis> LPUSH 命名 Mary (整数) 2 redis> LPUSH 命名 Alice (整数) 3 redis> LLEN 名称 (整数) 3 redis> LRANGE 名称 0 2 1)“爱丽丝” 2)“玛丽” 3)“约翰” redis> DEL 名称 (整数) 1 redis> LLEN 名称 (整数) 0 redis> LRANGE 名称 0 2 (空列表或集合)

【讨论】:

  • 有没有办法在一个原子操作中做到这一点? (“LRANGE 名称 0 2”和“DEL 名称”)
  • 一件事,使用 Del may create extra overhead,时间复杂度:O(N),其中 N 是要删除的键的数量。当要删除的键包含字符串以外的值时,该键的单个复杂度为 O(M),其中 M 是列表、集合、排序集或散列中元素的数量。删除包含字符串值的单个键是 O(1)。 docs
  • 这种方法很危险,因为它还会删除密钥的ttl
【解决方案2】:

2021 年 6 月 11 日更新

有不同的方法可以从 List 中删除所有元素:

第 1 步: 使用通用 DEL 命令删除 Redis 中的任何键,例如 Anurag's solution

DEL list

第 2 步: 使用LTRIM 命令并应用文档中的下一个条件

如果 start 大于列表的末尾,或者 start > end,则 结果将是一个空列表(这会导致键被删除)。

所以任何下一个命令都可以工作或Mohd Abdul Mujib's solution

LTRIM list 999 0

LTRIM list 1 0

LTRIM list 4 1

但是注意使用负数作为起始索引,如来自文档

start 和 end 也可以是负数,表示从 列表的末尾,其中 -1 是列表的最后一个元素,-2 是 倒数第二个元素等等。

下一个命令将删除列表下的所有元素 IF 列表包含多个元素 BUT IF 列表仅包含一个元素不会删除任何东西

LTRIM list -1 0

解释

第一种情况(列表包含多个元素) 索引-1 作为开始将转换为具有4 索引的最后一个元素(如果列表包含4 个元素)所以条件start > end 已应用

第二种情况(列表包括一个元素) 索引-1 作为开始将转换为具有0 索引的最后一个元素所以条件变为start == end 不是start > end

以上命令的示例:

redis 127.0.0.1:6379> RPUSH mylist four 1 3 1
(integer) 4
redis 127.0.0.1:6379> KEYS *
1) "test4"
2) "firstList"
3) "mylist"
redis 127.0.0.1:6379> LTRIM mylist 999 0
OK
redis 127.0.0.1:6379> KEYS *
1) "test4"
2) "firstList"
redis 127.0.0.1:6379> RPUSH mylist four 1 3 1
(integer) 4
redis 127.0.0.1:6379> KEYS *
1) "test4"
2) "firstList"
3) "mylist"
redis 127.0.0.1:6379> LTRIM mylist -1 0
OK
redis 127.0.0.1:6379> LRANGE mylist 0 -1
(empty list or set)
redis 127.0.0.1:6379> KEYS *
1) "test4"
2) "firstList"
redis 127.0.0.1:6379> RPUSH mylist four
(integer) 1
redis 127.0.0.1:6379> KEYS *
1) "test4"
2) "firstList"
3) "mylist"
redis 127.0.0.1:6379> LTRIM mylist -1 0
OK
redis 127.0.0.1:6379> KEYS *
1) "test4"
2) "firstList"
3) "mylist"

【讨论】:

  • 就像在接受答案的 cmets 中提到的那样:DEL 键也将删除列表的 ttl
  • 请更正您回答中的虚假声明; 也可以删除具有单个值的列表:stackoverflow.com/a/51497664/4960855
  • @EliadL 我更新了我的答案以清除我建议的解决方案,该解决方案仍然正确(在测试之后),在给出另一个解决方案时,他也正确,他的解决方案也适用于所有情况[列出一个或多个元素不止一个元素]
  • @ahmedhamdy 请注意,您答案中的开头句仍然是错误声明。
  • @EliadL 我编辑我的答案以更加明确,因为先前的答案不包括虚假声明,因为在某些情况下,具有相同开始和结束索引的确切命令(在开头的句子上)没有删除所有元素,例如我提到过,请尝试计算正确,最后感谢您的评论
【解决方案3】:

只需使用LTRIM。 ...啊,这里的魔法是使用start 大于 end

LTRIM key 99 0

还有……砰!有整个元素列表。就*噗*就在你眼前!!没有残留物,绝对没有问题。

注意:这将导致密钥被“删除”(如删除),如here

所述

...如果 start 大于列表的末尾,或者 start > end,结果将是一个空列表(这会导致 key 被删除)。

【讨论】:

  • 有什么理由比@Anurag 的回答更喜欢DEL key?似乎它们具有相同的效果。
  • 坦率地说,没有,没有时间研究基准,当我发现上述方法时,我只是在阅读文档,觉得不妨提一下。
  • 好的,谢谢!赞成是因为我可以想象重复使用LTRIM 的算法,很高兴知道当第二个参数低于第一个参数时会发生什么。我可以看到利用这种行为可以使一些代码更优雅。
【解决方案4】:

我试过了,它对我有用。只需将 myList 更改为您的列表名称并执行它 redis-cli KEYS "myList:*" | xargs redis-cli DEL

【讨论】:

  • 虽然这可行,但keys 是一个非常繁重的操作,涉及解析数据库中的每个键,在这种情况下,或者在大多数情况下,这是完全没有必要的
【解决方案5】:

这可能是一个较晚的响应,但我将它贴在这里以防万一有人仍然需要该功能。

简答

ltrim mylist 0 - (n+1) 其中 mylist 是键,n 是 mylist 的长度。

长答案

ltrim 的工作方式是,它需要两个索引并返回它们之间的元素,包括索引。

Ltrim 列表 startIndex endIndex

假设我们有一个 redis 列表,其键 mylist 包含 10 个条目:

ltrim mylist 0 5 会将列表修剪为从索引 0 到索引 5 的元素。并丢弃那些超出该范围的元素。

幸运的是,redis 列表操作支持负索引,这在某些情况下非常有用。通常当您不知道列表的长度时。

-1 是指最后一个元素,-2 是倒数第二个元素,等等。而 (-n) 是第一个元素。

超出范围的索引是无害的。如果结束索引大于列表的长度,redis 将其视为等于最后一个索引。

这就是为什么 ltrim mylist 0, -(n +1) 清除列表。这样做是因为 (-n) 相当于索引 0。向它添加 1 不会在该范围内留下任何元素,因为它将在第一个元素之前。

【讨论】:

  • 感谢您分享您的见解。作为答案的扩展,您可以简单地提供一个比列表大得多的 N 值,以保证删除所有项目。例如ltrim mylist 0 -99999.
【解决方案6】:

接受的答案是错误的。假设我有

redis 127.0.0.1:6379> KEYS * 
1) "newKey" 
2) "firstHash" 
3) "secondList" 
4) "test4" 
5) "firstList" 
6) "mylist" 

使用ahmed的例子,这实际上是正确的。 现在,如果我这样做:

DEL 'test4'

我最终得到:

1) "newKey" 
2) "firstHash" 
3) "secondList" 
4) "firstList" 
5) "mylist"` 

所以,我没有从“test4”列表中删除所有条目,我删除了 test4 本身。不是一回事。一点也不。我有一个小应用程序,其中列表键是从多个数据计算的哈希值(嗯,它们不是全部吗?),这些列表有时会被清除,但空列表和不存在列表的语义非常不同。 所以,不,我不想删除“myhashes”,我只想删除所有条目。

小心,哦,在这里徘徊的人。

【讨论】:

  • 如果您查看下面引用的页面,您会发现实际上语义是相同的!拍摄fromThe LPUSH command inserts a new element on the head, while RPUSH inserts a new element on the tail. A new list is created when one of this operations is performed against an empty key. Similarly the key is removed from the key space if a list operation will empty the list. These are very handy semantics since all the list commands will behave exactly like they were called with an empty list if called with a non-existing key as argument.
  • 从马嘴里说:“类似地,如果列表操作将清空列表,则从键空间中删除键。”那么,是 { [], [], [] } === { [] } 吗?不适合我。我想我们在不同的拓扑空间...... :)
  • 最初的问题是如何在 redis 中删除整个 List。因此,如果您删除密钥或删除所有条目并让 redis 自动删除密钥,则会得到相同的结果。所以我不确定你对 { [], [], [] } === { [] } 的意思。
  • 从列表中删除最后一个元素等于删除键。此链接甚至与 LIST 相同(使用 RPOPLPUSH 测试)bennadel.com/blog/…
猜你喜欢
  • 1970-01-01
  • 2013-04-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多