如何在Redis中合并两个列表

5

简介

我想要做一件听起来很简单的事情,但是到目前为止,我没有找到答案。我在一个redis 2.6.4独立服务器(非集群)上有两个列表:

list1 = [4, 5 ,6]

list2 = [1, 2, 3]

问题:
我需要将列表连接起来,得到如下结果:
list3 = list1 + list2

list3 = [4, 5, 6, 1, 2, 3] <- I need to preserve order, list1 and then list 2

list4 = list2 + list1

list4 = [1, 2, 3, 4, 5, 6]

问题

由于Redis使用链表来存储列表,因此我期望有一种简单直接的方法来处理它,是否存在这样的方法?通常在Redis中如何处理这种情况?

谢谢!

2个回答

1
最安全的做法是使用LUA脚本,这样可以保证生成的列表不会漏掉任何元素(并且可以轻松地保留顺序)。
如果无法使用LUA,则需要在客户端执行此操作,并使用WATCH命令监视这些键以进行更改(请参见Redis中的事务)。

我明白,但即使使用LUA,唯一的选择也是循环遍历其中一个列表中的所有项目并将其复制到另一个列表中?在这里,LUA绝对是一个选项。 - Sergio Ayestarán
是的,在最后它将成为O(N)操作,你需要连接的列表有多大? - Tommaso Barbugli
我有几个列表,总共包含1600-1800万个项目,其余的列表总共包含100-300万个项目。每个列表仅包含ID,而不是整个对象,但问题几乎相同,我无法找到一个O(1)操作来连接这些列表。通过“组合大小”,我指的是我正在尝试连接的两个列表的大小之和。 - Sergio Ayestarán
1
那么你有一个问题。另一种选择是不复制数据,而只是跟踪连接(例如,_list1 = [1,2,3]; list1 = ['_list1',]; 当您想要在list3中连接list1和list2时,将list3创建为['_list1','_list2'])。您的客户端需要足够聪明,能够处理这种间接性,并且能够遍历不同的列表。 - Tommaso Barbugli

1

这是使用Lua的Redis命令:

eval "for i,l in ipairs(ARGV) do for i,v in ipairs(redis.call('lrange',l,0,-1)) do redis.call('rpush',KEYS[1],v) end end" 1 list3 list1 list2

作为额外的奖励,您可以通过在末尾添加更多的列表键来指定任意数量的列表附加到您的主列表中。

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