sql >> Base de Datos >  >> NoSQL >> Redis

¿Cómo obtener claves que no coinciden con un patrón particular en redis?

IMPORTANTE: usa siempre SCAN en lugar de (el mal ) KEYS

La coincidencia de patrones de Redis tiene algunas funciones limitadas (consulte la implementación de stringmatchlen en util.c) y no proporciona lo que buscas ATM. Dicho esto, considera las siguientes rutas posibles:

  1. Extender stringmatchlen para que coincida con sus requisitos, posiblemente presentándolo como PR.
  2. Tenga en cuenta lo que está tratando de hacer:obtener un subconjunto de claves siempre será ineficaz a menos que las indexe, considere rastrear los nombres de todas las claves que no son de usuario (es decir, en un conjunto de Redis).
  3. >
  4. Si realmente insiste en escanear todo el espacio de claves y buscar coincidencias con patrones negativos, una forma de lograrlo es con un poco de magia Lua.

Considere el siguiente conjunto de datos y 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 (guarde esto 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

Salida:primera coincidencia regular, segunda vez el 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"