jomaint
jomaint

Reputation: 105

How do you use lua in redis to return usable result to nodejs

one of the module i am implementing for my mobile app api is to get all outstanding notifications from , submitting username.

i used a list called username:notifications to store all outstanding id of notifications. For example, in my test case, ['9','10',11'] is the result after calling for

lrange username:notifications 0 -1

So i wrote a lua script to get lrange and for each result,

hgetall notification:id 

And for some reason, lua could not send the table, result to nodejs in usable state. Wondering if anyone has a solution for multiple hgetall requests and returning them to nodejs

Here goes the rest of the code: -- @KEYS: "username" -- @ARGV: username

-- gets all fields from a hash as a dictionary
local hgetall = function (key)
  local bulk = redis.call('HGETALL', key)
    local result = {}
    local nextkey
    for i, v in ipairs(bulk) do
        if i % 2 == 1 then
            nextkey = v
        else
            result[nextkey] = v
        end
    end
end

local result = {}
local fields = redis.call('LRANGE' , ARGV[1], 0,-1) 

for i, field in ipairs(fields) do
  result[field] = hgetall('notification:'..field)   
end

return result

Upvotes: 1

Views: 952

Answers (1)

catwell
catwell

Reputation: 7020

You cannot return a "dictionary" from a Lua script, it is not a valid Redis type (see here).

What you can do is something like this:

local result = {}

local fields = redis.call('LRANGE' , ARGV[1], 0, -1) 

for i=1,#fields do
    local t = hgetall('notification:' .. fields[i])
    result[#result+1] = fields[i]
    result[#result+1] = #t/2
    for j=1,#t do
        result[#result+1] = t[j]
    end
end

return result

The result is a simple list with this format:

[ field_1, nb_pairs_1, pairs..., field_2, nb_pairs_2, ... ]

You will need to decode it in your Node program.

EDIT: there is another solution, probably simpler in your case: encode the result in JSON and return it as a string.

Just replace the last line of your code by:

return cjson.encode(result)

and decode from JSON in your Node code.

Upvotes: 1

Related Questions