Lua in Redis from JSON

ChrisS picture ChrisS · Mar 30, 2013 · Viewed 8.8k times · Source

I have a list of JSON strings stored in Redis that looks something like this:

[
   { "ID": 25, "DomainID": 23455, "Name": "Stuff", "Value": 23 }, 
   { "ID": 35, "DomainID": 23455, "Name": "Stuff", "Value": 10 }
]

The key would be something like "Event:23455".

Using a Lua script and ServiceStack.Redis how would I pull out an anonymous object containing only values where the value is less than 20?

So what I want to return would look like this:

[{ "ID": 35, "Value": 10}]

Thanks.

UPDATE 03/31/2013:

After trying what has been suggested I now have a new problem. A Lua script syntax error.

I'm getting a Lua syntax error about "expecting '=' near cjson". Here is the Lua script string (in C#) I am feeding to Redis:

string luaScript = "local tDecoded = cjson.decode(redis.call('GET', KEYS[1]));"
+ "local tFinal = {};"
+ "for iIndex, tValue in ipairs(tDecoded) do"
+ "     if tonumber( tValue.Value ) < 20 then"
+ "        table.insert(tFinal, { ID = tValue.ID, Value = tValue.Value});"
+ "     end"
+ "end"
+ "return cjson.encode(tFinal);";

Are there any Lua or Redis Lua experts out there that can see what might be the problem? i.e. Does the Lua syntax look correct?

UPDATE 04/02/2013

The parsing error was resolved by adding \n newline characters to end of each line like so.

string luaScript = "local tDecoded = redis.call('GET', KEYS[1]);\n"
+ "local tFinal = {};\n"
+ "for iIndex, tValue in ipairs(tDecoded) do\n"
+ "     if tonumber( tValue.Value ) < 20 then\n"
+ "        table.insert(tFinal, { ID = tValue.ID, Value = tValue.Value});\n"
+ "     else\n"
+ "         table.insert(tFinal, { ID = 999, Value = 0});\n"
+ "     end\n"
+ "end\n"
+ "return cjson.encode(tFinal);";

Unfortunately this works without errors but for some reason only returns "{}" or an empty list in the ServiceStack RedisClient. So I'm not there yet but I am one step closer.

Answer

hjpotter92 picture hjpotter92 · Mar 31, 2013

You can use LuaJSON available on GitHub or you can also try this JSON to Lua table parser for the task. The usage will be something like this(for the GitHub link):

local json = require( "json" )  -- or JSON.lua
local tDecoded = json.decode(sJSON)  -- sJSON is the original JSON string

local tFinal = {}

for iIndex, tValue in ipairs( tDecoded ) do
    if tonumber( tValue.Value ) < 20 then
        table.insert( tFinal, { ID = tValue.ID, Value = tValue.Value} )
    end
end

print( json.encode(tFinal) )