Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Lua in Redis from JSON

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.

like image 918
ChrisS Avatar asked Mar 30 '13 14:03

ChrisS


People also ask

Does Lua support JSON?

Introduction to Lua JSON. JSON stands for Javascript Object Notation, it works in the same way like any other programming language. JSON are very light weight and store anything inside them, mainly JSON in lua or any other programming language is used to transfer data from server to web pages and vice versa.

Is Redis written in Lua?

Redis lets users upload and execute Lua scripts on the server. Scripts can employ programmatic control structures and use most of the commands while executing to access the database. Because scripts execute in the server, reading and writing data from scripts is very efficient.

Is Redis Lua script Atomic?

Redis has the ability to execute Lua scripts on the server side. Lua scripts are executed atomically, that is, no other script or command will run while a script is running, which gives us the same transactional semantics as MULTI / EXEC .


1 Answers

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) )
like image 181
hjpotter92 Avatar answered Nov 15 '22 11:11

hjpotter92