【问题标题】:Removing hash attribute in redis with wildcard使用通配符删除redis中的哈希属性
【发布时间】:2014-06-26 00:42:42
【问题描述】:

在redis中,我们可以使用通配符,

KEYS foo* -> 查找密钥。

现在我想使用通配符删除 hashmap 的特定字段。考虑跟随例如。 创建哈希图

 HMSET myhash f "g" field1 "Hello" field2 "World" 

现在我想使用通配符删除密钥

 DEL myha*

有可能吗?

我还想使用通配符从 SET 中删除特定字段,例如

DEL myhash field*

这也可以吗?

提前谢谢。

【问题讨论】:

  • DEL myha*,可以参考stackoverflow.com/questions/4006324/…。但是对于 DEL myhash field*,恐怕你需要一个脚本来做到这一点。
  • @BrandonGao 感谢您的关注。所以这是可能的。你能给出任何例子或资源链接吗?
  • 可以参考redis原文档编写脚本。但我认为您需要使用 HDEL 来回答第二个问题。
  • @BrandonGao 非常感谢你
  • 使用 SCAN 和 HSCAN。除非总共有很少的键,否则不要使用 KEYS(根本!)。 SCAN 和 HSCAN 的结果可以放入 Lua 脚本调用中,序列化为 msgpack,以按批次删除。建议的批量大小:1000。

标签: python redis key-value nosql


【解决方案1】:

要使用通配符从 SET 中删除特定字段,您可以使用此 LUA 脚本:

-- ARGV[1] - hash key
-- ARGV[1] - lua pattern 
local fields = redis.call("HKEYS", ARGV[1]);
local retVal = {};
for key, value in pairs(fields) do
    if (string.match(value, ARGV[2])) then
        table.insert(retVal, value);
        redis.call("HDEL", ARGV[1], value);
    end
end

return retVal;

这个脚本复杂度O(n)。脚本返回与给定模式匹配的已删除字段。看string.match tutorial到lua模式匹配功能。

PHPphpredis 中的示例用法:

$r = new Redis();
$r->connect('127.0.0.1');

for ($i = 1; $i < 1000; $i++) {
    $r->hSet('myhash', 'aaa' . mt_rand(0, PHP_INT_MAX), 1);
}
$r->hSet('myhash', 'bad', 1);

$script = <<< SCR
    local fields = redis.call("HKEYS", ARGV[1]);
    local retVal = {};
    for key, value in pairs(fields) do
        if (string.match(value, ARGV[2])) then
            table.insert(retVal, value);
            redis.call("HDEL", ARGV[1], value);
        end
    end

    return retVal;
SCR;

var_dump($r->eval($script, ['myhash', '^b.+']));

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-02-06
    • 1970-01-01
    • 2012-07-02
    • 1970-01-01
    • 1970-01-01
    • 2017-04-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多