在redis-rb中删除多个键

sha*_*ott 16 ruby redis

在Rails应用程序中使用redis-rb,以下内容不起作用:

irb> keys = $redis.keys("autocomplete*")
=> ["autocomplete_foo", "autocomplete_bar", "autocomplete_bat"]
irb> $redis.del(keys)
=> 0
Run Code Online (Sandbox Code Playgroud)

这很好用:

irb> $redis.del("autocomplete_foo", "autocomplete_bar")
=> 2
Run Code Online (Sandbox Code Playgroud)

我错过了一些明显的东西吗 来源只是:

# Delete a key.
def del(*keys)
  synchronize do
    @client.call [:del, *keys]
  end
end
Run Code Online (Sandbox Code Playgroud)

看起来像我应该工作传递一个数组...?

小智 32

对splat运算符的工作方式进行一些编码探索:

def foo(*keys)
  puts keys.inspect
end

>> foo("hi", "there")
["hi", "there"]

>> foo(["hi", "there"])
[["hi", "there"]]

>> foo(*["hi", "there"])
["hi", "there"]
Run Code Online (Sandbox Code Playgroud)

因此,传入一个常规数组会导致该数组被计算为单个项目,因此您可以在方法中的数组中获取一个数组.如果在调用方法时在数组前加上*:

$redis.del(*keys)
Run Code Online (Sandbox Code Playgroud)

这让方法知道解压缩/不接受任何进一步的参数.所以这应该解决你所拥有的问题!

只是为了进一步澄清,这有效:

>> foo("hello", *["hi", "there"])
Run Code Online (Sandbox Code Playgroud)

这会导致语法错误:

>> foo("hello", *["hi", "there"], "world")
Run Code Online (Sandbox Code Playgroud)


Mar*_*rom 12

对于我正在研究的Rails应用程序,我需要测试加载和卸载redis数据的结果.

命名空间由环境决定,避免与开发交互.这很好用.

def clear_redis_cache
  keys = $redis.keys "#{namespace}*"
  $redis.del(*keys) unless keys.empty?
end
Run Code Online (Sandbox Code Playgroud)


Rob*_*rty 6

使用 所返回的枚举器可以更好地实现这一点scan_each

scan_each(match: 'autocomplete_*').each do |key|
  del key
end
Run Code Online (Sandbox Code Playgroud)

这不会一次性将所有匹配的键加载到内存中,因此不会受到本地内存的限制。

  • _这个_,这么多!我使用原始发布者的方法扫描整个数据库以查找匹配的键,然后尝试删除包含数千个键的数组。花了一个多小时。这个“scan_each”方法将其时间缩短至 10 分钟! (2认同)