批量删除Redis哈希表中基于哈希键名称的值。

类似这个问题,但需要解决哈希键而不是普通键的解决方案:如何使用Redis原子地删除匹配模式的键

我有很多带有前缀“prefix:”的哈希。

在每个哈希下面有一堆键,例如“cc_XX”,其中“XX”是两个字母的代码。

我需要以某种方式循环遍历所有redis哈希,并以某种方式删除每个cc_XX子键,并寻找用cli / lua做到这一点的方法(对任何一种方法都不怎么擅长)。

非常感谢任何建议。

点赞
用户1114486
用户1114486

下面的[EVAL脚本](http://redis.io/commands/eval)应该可以满足您的需求:

local keys = redis.call('KEYS',KEYS [1])
for i,k in ipairs(keys)do
    local res = redis.call('HKEYS',k)
    for j,v in ipairs(res)do
        if string.find(v,ARGV [1])then
            redis.call('HDEL',k,v)
        end
    end
end

您需要通过提供以下参数来调用它:

EVAL <script> 1 prefix:* cc_..

请注意,它会阻塞Redis事件循环,直到脚本完成,如果您有大量的键,则可能会冻结Redis一段时间。原子性有一个价格。

更新:

如果您不需要原子性,则以下脚本将避免过长时间地阻塞Redis(但请注意,如果您有大量全局键或其中一个哈希对象很大,它仍将被阻塞:无法避免此问题)。

./redis-cli keys 'prefix:*' | awk '
BEGIN {
    script = "local res = redis.call('\''HKEYS'\'',KEYS[1]); \
          for j,v in ipairs(res) do                          \
            if string.find(v,ARGV[1]) then                   \
              redis.call('\''HDEL'\'',KEYS[1],v);            \
            end                                              \
          end"
}
{
    printf "EVAL \"%s\" 1 %s cc_..\n", script, $1
}' | ./redis-cli

(在bash中测试)

2013-06-21 14:38:04
用户659615
用户659615

我们在 Redis 中存储哈希值的方式是,我们在哈希表中用对象类型对哈希元素 id 键进行后缀。有时在数据模型中,我们更新一个对象并且需要在部署后删除所有给定对象类型的哈希元素。我们希望在不必删除整个哈希表的情况下完成此操作。

例如:

127.0.0.1:6379> keys client*
1) "client"

127.0.0.1:6379> type client
hash

127.0.0.1:6379> hkeys client
 1) "123-obj1"
 2) "123-obj2"
 3) "123-obj3"
 4) "123-obj4"
 5) "123-obj5"
 6) "456-obj1"
 7) "456-obj2"
 8) "456-obj3"
 9) "456-obj4"
10) "456-obj5"

如果我们在应用程序中添加一个新字段到 obj5 并设置一个默认值,我们需要运行“HDEL client *-obj5”的等效命令。然而,这在 redis-cli 中不起作用。

我已经发现以下命令通过 BASH 工作:

redis-cli HKEYS 'client' | grep obj5 | awk '{ printf "HDEL client %s\n", $1 }' | redis-cli

如果您在环境中使用不同的 Redis 数据库,请添加“-n X”开关,这相当于在 redis-cli 中选择数据库 X。在本例中,选择数据库 4:

redis-cli -n 4 HKEYS 'client' | grep obj5 | awk '{ printf "HDEL client %s\n", $1 }' | redis-cli -n 4
2015-10-07 16:56:17