ВАЖНО: винаги използвайте SCAN
вместо (злото ) KEYS
Съвпадението на шаблоните на Redis е донякъде функционално ограничено (вижте внедряването на stringmatchlen
в util.c) и не предоставя това, което търсите банкомат. Въпреки това, помислете за следните възможни маршрути:
- Разширете
stringmatchlen
за да отговаря на вашите изисквания, евентуално да го изпратите като PR. - Помислете какво се опитвате да направите – извличането на подмножество от ключове винаги ще бъде неефективно, освен ако не ги индексирате, вместо това помислете за проследяване на имената на всички непотребителски ключове (напр. в Redis Set).
- Ако наистина настоявате да сканирате цялото ключово пространство и да съпоставите с отрицателни модели, един от начините да постигнете това е с малко магия на Lua.
Помислете за следния набор от данни и скрипт:
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 (запазете това като 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
Изход - за първи път редовно съвпадение, втори път допълнение:
[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"