1

In redis, we can use wildcard like,

KEYS foo* -> to find keys.

Now I want to delete particular field of hashmap using wildcard. Consider following eg. creating hashmap

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

now I want to delete key using wildcard like

 DEL myha*

Is it possible?

Also I want to delete particular field from SET using wildcard like

DEL myhash field*

Is this also possible?

Thanx in advance.

Community
  • 1
  • 1
userx
  • 806
  • 1
  • 11
  • 23
  • For DEL myha*, you can refer to http://stackoverflow.com/questions/4006324/how-to-atomically-delete-keys-matching-a-pattern-using-redis . But for DEL myhash field*, I'm afraid you need a script to do that. – Brandon Gao May 08 '14 at 15:40
  • @BrandonGao thnx man for taking interest. So it is possible. Can you give any example or resource link? – userx May 08 '14 at 17:28
  • 1
    you can refer to the original redis doc to write the script. But I think you need to use HDEL for your second question. – Brandon Gao May 09 '14 at 02:08
  • @BrandonGao thnk u so much – userx May 09 '14 at 06:41
  • 3
    Use SCAN and HSCAN. Don't use KEYS (at all!) unless there are very few keys in total. The results from SCAN and HSCAN can be put in a Lua script call, serialized as msgpack, to delete per batch. Suggested batch size: 1000. – Tw Bert May 09 '14 at 21:33

1 Answers1

2

To delete particular fields from SET using wildcards you can use this LUA script:

-- 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;

This script has complexity O(n). Script return deleted fields matched by given pattern. Look at string.match tutorial to lua pattern matching features.

Sample usage in PHP with phpredis:

$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.+']));
Nick Bondarenko
  • 6,211
  • 4
  • 35
  • 56