I have a Redis list with some values
LRANGE LIST 0 -1
> 1
> 2
> 3
And I want to RPUSH
these values into another list. How can this be done? I've tried to do it with MULTI
and EXEC
, but with no results.
A server-side Lua script is more convenient that a WATCH/MULTI/EXEC block to implement this kind of operation.
Here is an example of a script with takes two lists (source and destination) as parameters, and two integers defining a range in the source list. It then pushes the corresponding items to the destination list.
> rpush foo 1 2 3 4
(integer) 4
> rpush bar x
(integer) 1
> eval "local res = redis.call( 'lrange', KEYS[1], ARGV[1], ARGV[2] ); return redis.call( 'rpush', KEYS[2], unpack(res) ); " 2 foo bar 0 -1
(integer) 5
> lrange bar 0 -1
1) "x"
2) "1"
3) "2"
4) "3"
5) "4"
if you want to move the key to a new key, you can use RENAME command , the only will change the key name RENAME COMMAND
this approach
> eval "local res = redis.call( 'lrange', KEYS[1], ARGV[1], ARGV[2] ); return redis.call( 'rpush', KEYS[2], unpack(res) ); " 2 foo bar 0 -1
may produce "too many results to unpack" error when list is too long.
here is a script to do this
-- @desc: copies a list with POP and PUSH
-- @usage: redis-cli --eval copy_list_with_popnpush.lua <source> <dest>
local s = KEYS[1]
local d = KEYS[2]
local l = redis.call("LLEN", s)
local i = tonumber(l)
while i > 0 do
local v = redis.call("RPOPLPUSH", s, s)
redis.call("LPUSH", d, v)
i = i - 1
end
return l
some other awesome scripts https://gist.github.com/itamarhaber/d30b3c40a72a07f23c70
You can move them from one list to another and LPUSH
them using the RPOPLPUSH
command multiple times:
RPOPLPUSH old_list new_list
RPOPLPUSH old_list new_list
RPOPLPUSH old_list new_list
Of course you might want to do this in a client program or script, there's no way I can find to move all members of a list to another list.