在Redis列表中按索引插入值

11

有没有办法通过索引向Redis列表中插入值?

LINSERT可以通过进行插入,但这似乎有点不可靠,因为相同的值可能在列表中多次出现。

3个回答

2

有一个解决方法可能会比较慢,因为所有操作都是O(n)的。

  • 使用LIndex将旧值保存在客户端。
  • 使用LSet设置一个永远不会插入到列表中的标记值。
  • 使用LINSERT在标记值后插入2个值(新值、旧保存的值)。
  • 使用LRem删除标记值。
  • 所有操作应该在事务中进行。

标签值的目的是什么?我们不能通过使用LINDEX获取指定索引处的值,然后使用LINSERT在步骤1中检索到的旧值之前插入新值来实现相同的结果吗? - user1491636
标签值旨在是唯一的 - 使用LINDEX获取指定索引处的值,并将其用作插入的支点,仅在目标索引处的值恰好唯一时才能正常工作。因此,首先插入标签是有意义的。 - Harry

0

如果您需要不重复的元素,则Redis的set是更合适的数据结构,或者使用排序集合(sorted set)来对元素进行排序。列表(lists)更适用于推送和弹出操作。


这不是重点,许多情况下需要一个列表,这个列表可能有意包含重复项,然而使用“LINSERT”命令时,我们无法指定在哪个元素之前或之后插入新元素。 - Pezhvak

0

开发yinqiwen的答案只是为了澄清:

假设想要在名为test的列表中第二个条目之前插入一个值。

从空键开始,填充数据:

127.0.0.1:6379> del test
(integer) 1
127.0.0.1:6379> rpush test "uno"
(integer) 1
127.0.0.1:6379> rpush test "dos"
(integer) 2
127.0.0.1:6379> rpush test "tres"
(integer) 3
127.0.0.1:6379> lrange test 0 -1
1) "uno"
2) "dos"
3) "tres"

选取要插入位置之后的数据并保留,然后用任何标签值替换它。

127.0.0.1:6379> lindex test 1
"dos"
127.0.0.1:6379> lset test 1 "my_tag"
OK
127.0.0.1:6379> lrange test 0 -1
1) "uno"
2) "my_tag"
3) "tres"

在标签后插入旧值。

127.0.0.1:6379> linsert test after my_tag dos
(integer) 4
127.0.0.1:6379> lrange test 0 -1
1) "uno"
2) "my_tag"
3) "dos"
4) "tres"

在标签后插入一个值,比如说“插入”值

127.0.0.1:6379> linsert test after my_tag insertion
(integer) 5
127.0.0.1:6379> lrange test 0 -1
1) "uno"
2) "my_tag"
3) "insertion"
4) "dos"
5) "tres"

现在,删除标签,插入的数据将会在第二个值之前:

127.0.0.1:6379> lrem test 0 my_tag
(integer) 1
127.0.0.1:6379> lrange test 0 -1
1) "uno"
2) "insertion"
3) "dos"
4) "tres"

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接