我有一个脚本
local fields = redis.call('hkeys', 'a:hash:full:of:stuff');
local retval = {};
for i, field in pairs(fields) do
if((string.match(tostring(field),'ev')) ~= nil) then
retval[i] = {field, (string.match(tostring(field),'ev') ~= nil) }
end
end
return retval
此脚本返回一个空列表
当我将if
语句更改为
if((string.match(tostring(field),'.')) ~= nil) then
...
我得到一个包含以下内容的长列表
...
...
60) 1) "applet:1:metric:viewelement:20130607"
2) (nil)
61) 1) "applet:1:total_events:20130529"
2) (integer) 1
...
...
如果我用
替换if语句if(1)
我得到相同长的密钥列表
我也尝试过使用string.find
,它也有类似的行为。
似乎作为模式的唯一事情是,如果匹配的字符串在字符串中出现多次,或者如果它出现在开头,则if
语句将通过。我不能确定这一点,但它可能会有所帮助。
我使用以下命令运行此脚本
$ redis-cli eval "$(cat get_keys.lua)" 0
答案 0 :(得分:2)
if((string.match(tostring(field),'ev')) ~= nil)
。你可以if(string.match(tostring(field),'ev'))
。some_table[1]
,some_table[2]
和some_table[5]
然后返回数组,它看起来就像在some_table[2]
处结束。由于您只在if语句通过时设置数组,如果它在retval[1]
上失败,则不会返回任何数组的其余部分。 简单的解决方法是:
local fields = redis.call('hkeys', 'a:hash:full:of:stuff');
local retval = {};
for i, field in pairs(fields) do
if(string.match(tostring(field),'ev')) then
retval[i] = {field, (string.match(tostring(field),'ev') ~= nil) }
else retval[i] = 'some_nil_value'
end
end
return retval
我认为您也可以使用table default values,但我还没有玩过这些,所以不能在这里提供太多信息。
[编辑] OP表示他不想要零占位符。在这种情况下,可以使用以下内容:
local fields = redis.call('hkeys', 'a:hash:full:of:stuff');
local retval = {};
for i, field in pairs(fields) do
if(string.match(tostring(field),'ev')) then
retval[#retval+1] = {field, (string.match(tostring(field),'ev') ~= nil) }
end
end
return retval
答案 1 :(得分:0)
Eli的回答是有效的,但我认为这是一个微妙的问题,就像在Lua中处理列表一样。我想解释一下我的想法。
因此,作为测试,我在retval
中插入了一个额外的字段,偶尔它是零。我注意到在那些调用中,列表的其余部分没有返回。
我认为幕后发生的事情是redis正在整个列表中工作,但是当它返回时,它会在第一个nil
被截断。所以有时会有一个列表,有时则没有。作为一个黑客,我重写了脚本
local fields = redis.call('hkeys', 'a:hash:full:of:stuff');
local retval = {};
local i = 0
for j, field in pairs(fields) do
if string.find(field,"ev") then
retval[i] = {field, string.match(field,'ev') }
i = i+1;
end
end
return retval
它有效!
所以Eli的回答是有效的,因为retval
没有被截断。但是,当您需要解析返回的列表时,它会占用更多的带宽和CPU时间