如何在Redis中删除与模式匹配的键列表?

4

使用 Ruby Redis 客户端

我有一个包含值列表的键,它们遵循以下模式:

campaign_id|telephone|query_id

这里有一个包含成千上万个元素的列表,我想要做的是从Redis列表中删除所有查询ID为4的元素。是否可以通过某种模式匹配来实现呢?请问能否给出一个示例,因为我已经阅读了其他问题,但感到有些困惑。


list.reject { |e| e =~ /|#{query_id}$/ } - Aleksei Matiushkin
我是指从Redis中实际删除它们,而不是从返回的内容中拒绝它们。 - Jake McAllister
1个回答

1
你基本上有两个选择:a)在你的(RoR)应用程序中完成,或者b)在Redis中完成。
我不是RoR专家,无法提供如何建议,但请注意,如果选择a),你基本上将把整个列表移动到你的应用程序中进行过滤。列表越大,通过网络传输所需的时间就越长。
选择b)意味着你将直接在Redis中过滤列表-当你使用Lua时,这可以简单高效地完成。例如:
$ cat dellistbyqueryid.lua
-- removes a range of list elements that confirm to a given
-- query_id. Elements are stored as: 'campaign_id|telephone|query_id'
-- KEYS[1] - a list
-- ARGV[1] - a query_id
-- return: number of elements removed

local l = tonumber(redis.call('LLEN', KEYS[1]))
local n = 0

while l > 0 do
  local curr = redis.call('LINDEX', KEYS[1], -1)
  local id = curr:match( '.*|.*|(.*)' )
  if id == ARGV[1] then
    redis.call('RPOP', KEYS[1])
    n = n + 1
  else
    redis.call('RPOPLPUSH', KEYS[1], KEYS[1])
  end
  l = l - 1
end

return n

输出:

$ redis-cli LPUSH list "foo|bar|1" "baz|qaz|2" "lua|redis|1"
(integer) 3
$ redis-cli --eval dellistbyqueryid.lua list , 1
(integer) 2
$ redis-cli LRANGE list 0 -1
1) "baz|qaz|2"

但是实际的删除部分在哪里?我猜作者问的是从列表中删除值而不是过滤输出。关于情况a),这种情况基本上意味着在RoR中过滤所有列表,然后用过滤后的列表替换现有列表吗?因为LREM不支持通过regexp删除或按索引删除。 - RuslanN
@RuslanN 你说得非常非常正确。我立刻进行编辑。 - Itamar Haber

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