2
votes

I want to delete redis keys that DO NOT match a particular pattern. Redis data looks like this -

prefix9_key1
prefix9_key2
prefix11_key1
prefix11_key2
prefix2_key1
prefix2_key2

These prefix values are randomly generated numbers (example 1123, 3422, 9879).

I know what my current prefix is (let's say it is prefix11). But there is no way to know what were the earlier prefixes being used. I want to delete all keys that DO NOT use current prefix value (prefix2* and prefix9*).

I read many posts mentioning deleting keys matching a pattern. I want to delete keys that do not match a particular pattern.

2

2 Answers

1
votes

From the docs:

h[^e]llo matches hallo, hbllo, ... but not hello

But, the specific example you gave is a bit tricky. Here is how you can get the desired filtering:

=>redis-cli keys \*
1) "pre1_234"
2) "pre3_234"
3) "pre11_asv"
4) "pre2_234"

=>redis-cli keys 'pre[^1]*' | redis-cli keys 'pre?[^1]*'
1) "pre1_234"
2) "pre3_234"
3) "pre2_234"

To me redis-cli keys 'pre[^1][^1]'* should have given the desired output. But it's not working. The pattern matcher short circuits at the first [^1] and hence pre1_234 is not part of the output. The vagaries of regex :)

You can use lua script for atomic deletion in one call to Redis. See this.

0
votes

You need a lua UDF for this (below example uses jedis as redis client),

String DELETE_SCRIPT = "local keys = redis.call('keys', '%s')" +
                       "  for i,k in ipairs(keys) do" + 
                       "    local res = redis.call('del', k)" + 
                       "  end";

Your pattern will be a string input to the method with the prefix like prefix[^11]*

public void deleteOthers (String pattern) {
    String luaScript = String.format(DELETE_SCRIPT, pattern);
    jedis.eval(luaScript);
}

Call to this method would be something like,

deleteOthers("prefix[^11]*");