在Redis中,keys user*
将打印以user
开头的所有密钥。
例如:
keys user*
1) "user2"
2) "user1"
现在,我想要打印所有不以user
开头的密钥。
我怎么能这样做?
答案 0 :(得分:23)
重要提示:始终使用SCAN
代替(邪恶)KEYS
Redis'模式匹配在某种程度上受到功能限制(请参阅util.c中的stringmatchlen
的实现),并未提供您寻求ATM的内容。也就是说,考虑以下可能的路线:
stringmatchlen
以符合您的要求,可能会将其作为公关提交。考虑以下数据集和脚本:
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
输出 - 第一次常规匹配,第二次补充:
foo@bar:~$ redis-cli --eval scanregex.lua , "^user"
1) "user:1"
foo@bar:~$ redis-cli --eval scanregex.lua , "^user" 1
1) "use:the:force"
2) "non:user"
答案 1 :(得分:7)
@Karthikeyan Gopall你在上面的评论中钉了它,这给我节省了很多时间。谢谢!
以下是如何以各种组合方式使用它来获得您想要的内容:
redis.domain.com:6379[1]> set "hello" "foo"
OK
redis.domain.com:6379[1]> set "hillo" "bar"
OK
redis.domain.com:6379[1]> set "user" "baz"
OK
redis.domain.com:6379[1]> set "zillo" "bash"
OK
redis.domain.com:6379[1]> scan 0
1) "0"
2) 1) "zillo"
2) "hello"
3) "user"
4) "hillo"
redis.domain.com:6379[1]> scan 0 match "[^u]*"
1) "0"
2) 1) "zillo"
2) "hello"
3) "hillo"
redis.domain.com:6379[1]> scan 0 match "[^u^z]*"
1) "0"
2) 1) "hello"
2) "hillo"
redis.domain.com:6379[1]> scan 0 match "h[^i]*"
1) "0"
2) 1) "hello"
答案 2 :(得分:4)
根据redis keys documentation,该命令支持 glob 样式模式,不是正则表达式。
如果你查看文档,你会看到"!"字符与正则表达式的对立面并不特殊。
这是我在自己的数据库中运行的一个简单测试:
redis 127.0.0.1:6379> set a 0
OK
redis 127.0.0.1:6379> set b 1
OK
redis 127.0.0.1:6379> keys *
1) "a"
2) "b"
redis 127.0.0.1:6379> keys !a
(empty list or set) // I expected "b" here
redis 127.0.0.1:6379> keys !b
(empty list or set) // I expected "a" here
redis 127.0.0.1:6379> keys [!b]
1) "b"
redis 127.0.0.1:6379> keys [b]
1) "b"
redis 127.0.0.1:6379> keys [ab]
1) "a"
2) "b"
redis 127.0.0.1:6379> keys ![b]
(empty list or set)
所以我只是不想通过keys命令实现你想要实现的目标。
此外,keys命令不太适合生产环境,因为它会锁定整个redis数据库。
我建议使用scan命令获取所有密钥,将它们存储在本地,然后使用LUA删除它们
答案 3 :(得分:0)
这里有一个使用原生 redis 命令(不需要 Lua 脚本或任何东西)来实现这一点的技巧。
如果您能够控制插入新密钥的时间(您想要保留的密钥,删除问题中的所有其他内容),您可以:
Redis 会自动删除所有旧的键,而你只会留下你想要的新键。