BELANGRIJK: gebruik altijd SCAN
in plaats van (het kwaad ) KEYS
De patroonovereenkomst van Redis is enigszins functioneel beperkt (zie de implementatie van stringmatchlen
in util.c) en biedt niet datgene wat u ATM zoekt. Dat gezegd hebbende, overweeg de volgende mogelijke routes:
- Verleng
stringmatchlen
om aan uw vereisten te voldoen, eventueel indienen als een PR. - Bedenk wat je probeert te doen - het ophalen van een subset sleutels zal altijd inefficiënt zijn, tenzij je ze indexeert, overweeg in plaats daarvan de namen van alle niet-gebruikerssleutels bij te houden (bijvoorbeeld in een Redis-set). >
- Als je er echt op staat om de hele keyspace te scannen en te matchen met negatieve patronen, kun je dat onder meer bereiken met een beetje Lua-magie.
Overweeg de volgende dataset en 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 (sla dit op 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
Uitgang - eerste keer regelmatig matchen, 2e keer het complement:
[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"