1
votes

I'm trying to search for field value in hash using Lua script and I'm doing something wrong :) I have key "articles" which is zset holding article IDs and keys article:n where "n" is the article number. The following script:

local ids = redis.call("zrange", 'articles', '0', '-1')
local ret = {}
for k, id in pairs(ids) do
    local row = redis.call("hgetall", "article:"..id)
    ret[k] = row
end
return ret

returns this:

1)  1) "slug"
    2) "first-title"
    3) "title"
    4) "first title"
2)  1) "slug"
    2) "second-title"
    3) "title"
    4) "second title"

Than I'm trying to include condition to return only keys containing string "second" in title but it returns nothing.

local ids = redis.call("zrange", 'articles', '0', '-1')
local ret = {}
for k, id in pairs(ids) do
    local row = redis.call("hgetall", "article:"..id)
    if (string.find(row[4], "second")) then
        ret[k] = row
    end
end
return ret

Please could you help me?

2
Regardless the issue with the condition, you should note that all key names that are used in the script should be passed using the KEYS argument table - dynamically accessing keys (e.g. based on the contents of a Sorted Set range) is not ensured to work in a clustered environment. - Itamar Haber

2 Answers

2
votes

The table you returned from lua, must be an array whose index staring from 1.

However, In your example, only the second article matches the condition, and its index is 2. So you are, in fact, setting the table as: ret[2] = row. Since the returned table is NOT an array whose index starting from 1, Redis takes it as an empty array, and you get nothing.

Solution:

local ids = redis.call("zrange", 'articles', '0', '-1')
local ret = {}
local idx = 1;  -- index starting from 1
for k, id in pairs(ids) do
    local row = redis.call("hgetall", "article:"..id)
    if (string.find(row[4], "second")) then
        ret[idx] = row   -- set table
        idx = idx + 1    -- incr index by 1
    end
end
return ret
0
votes

Try this condition

if (string.find(row[4], "second") ~= nil) then