QUAN TRỌNG: luôn sử dụng SCAN
thay vì ( cái ác ) KEYS
Đối sánh mẫu của Redis hơi hạn chế về mặt chức năng (xem việc triển khai stringmatchlen
trong use.c) và không cung cấp cái mà bạn tìm kiếm ATM. Điều đó nói rằng, hãy xem xét các tuyến đường khả thi sau:
- Mở rộng
stringmatchlen
để phù hợp với yêu cầu của bạn, có thể gửi nó như một bài PR. - Cân nhắc những gì bạn đang cố gắng thực hiện - tìm nạp một tập hợp con các khóa luôn không hiệu quả trừ khi bạn lập chỉ mục chúng, hãy cân nhắc theo dõi tên của tất cả các khóa không phải của người dùng (tức là trong Redis Set).
- Nếu bạn thực sự kiên định về việc quét toàn bộ không gian phím và khớp với các mẫu phủ định, một cách để thực hiện điều đó là sử dụng một chút phép thuật của Lua.
Hãy xem xét tập dữ liệu và tập lệnh sau:
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 (lưu cái này dưới dạng 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
Đầu ra - đối sánh thông thường lần đầu, bổ sung lần thứ hai:
[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"