Redis
 sql >> Base de Dados >  >> NoSQL >> Redis

como obter chaves que não correspondem a um padrão específico no redis?


IMPORTANTE: sempre use SCAN em vez de (o mal ) KEYS


A correspondência de padrões do Redis é um pouco limitada funcionalmente (veja a implementação de stringmatchlen em util.c) e não fornece o que você procura ATM. Dito isso, considere as seguintes rotas possíveis:
  1. Estender stringmatchlen para atender aos seus requisitos, possivelmente enviando-o como PR.
  2. Considere o que você está tentando fazer:buscar um subconjunto de chaves sempre será ineficiente, a menos que você as indexe. Em vez disso, considere rastrear os nomes de todas as chaves que não são de usuário (por exemplo, em um Redis Set).
  3. >
  4. Se você for realmente insistente em escanear todo o keyspace e comparar com padrões negativos, uma maneira de conseguir isso é com um pouco de magia Lua.

Considere o seguinte conjunto de dados e script:
127.0.0.1:6379> dbsize
(integer) 0
127.0.0.1:6379> set user:1 1
OK
127.0.0.1:6379> set use:the:force luke
OK
127.0.0.1:6379> set non:user a
OK

Lua (salve como scanregex.lua ):
local re = ARGV[1]
local nt = ARGV[2]

local cur = 0
local rep = {}
local tmp

if not re then
  re = ".*"
end

repeat
  tmp = redis.call("SCAN", cur, "MATCH", "*")
  cur = tonumber(tmp[1])
  if tmp[2] then
    for k, v in pairs(tmp[2]) do
      local fi = v:find(re) 
      if (fi and not nt) or (not fi and nt) then
        rep[#rep+1] = v
      end
    end
  end
until cur == 0
return rep

Saída - primeira correspondência regular, segunda vez o complemento:
[email protected]:~$ redis-cli --eval scanregex.lua , "^user"
1) "user:1"
[email protected]:~$ redis-cli --eval scanregex.lua , "^user" 1
1) "use:the:force"
2) "non:user"