Redis
 sql >> Datenbank >  >> NoSQL >> Redis

Wie bekomme ich Schlüssel, die nicht mit einem bestimmten Muster in Redis übereinstimmen?

WICHTIG: Verwenden Sie immer SCAN statt (das Böse ) KEYS

Der Musterabgleich von Redis ist funktional etwas eingeschränkt (siehe die Implementierung von stringmatchlen in util.c) und bietet nicht das, wonach Sie suchen ATM. Beachten Sie jedoch die folgenden möglichen Routen:

  1. Erweitern Sie stringmatchlen um Ihren Anforderungen zu entsprechen, möglicherweise als PR einzureichen.
  2. Überlegen Sie, was Sie versuchen - das Abrufen einer Teilmenge von Schlüsseln wird immer ineffizient sein, es sei denn, Sie indizieren sie. Erwägen Sie stattdessen, die Namen aller Nicht-Benutzerschlüssel (z. B. in einem Redis-Satz) zu verfolgen.
  3. Wenn Sie wirklich darauf bestehen, den gesamten Schlüsselraum zu scannen und mit negativen Mustern abzugleichen, können Sie dies mit ein wenig Lua-Magie erreichen.

Betrachten Sie das folgende Dataset und Skript:

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 (speichern Sie dies als 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

Ausgabe - beim ersten Mal das reguläre Matching, beim 2. Mal das Komplement:

[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"