如何在Redis的Lua cjson中检查nil/null? [英] How to check for nil/null in Redis' Lua cjson?
问题描述
我有一个带代码块的lua脚本,如下所示:
I have a lua script with code block as below:
local call_data = cjson.decode(ARGV[1])
local other_data = cjson.decode(ARGV[2])
local data = {}
local next = next
local populate_data = function(source)
if next(source) == nil then
return
end
for property,value in pairs(source) do
redis.call('HSET', KEYS[2], property, value)
end
end
populate_data(call_data)
populate_data(other_data)
当我尝试使用以下命令KEYS和ARGV运行脚本时:-
When I try to run the script with the following command KEYS and ARGV as:-
redis-cli --eval dialed.lua "inflight_stats:18" "calls:AC443d7a8111a96ba8074f54a71f0521ce:CA1ec49703eee1959471c71506f43bb42e:dialed" , "{\"from\":\"+18035224181\",\"to\":\"+919943413333\",\"sid\":\"CA1ec49703eee1959471c71506f43bb42e\",\"status\":\"queued\",\"direction\":\"outbound-api\",\"date_created\":null,\"account_sid\":\"AC443d8a8111a96ba8074f54a71f0521ce\"}" "{\"phone\":\"919943413333\",\"campaign_id\":18,\"caller_session_sid\":\"CA828b163153bf5cc301ef5285e38925f9\"}" 0
错误:-
(error) ERR Error running script (call to f_08dcc69ee8baa0200e0cf552948ab4bc338c9978): @user_script:11: @user_script: 11: Lua redis() command arguments must be strings or integers
推荐答案
TL; DR表示cjson.decode()
返回的值,请使用cjson.null
与JSON的null
值进行比较.
TL;DR for values returned by cjson.decode()
, use cjson.null
to compare to JSON's null
value.
说明:Lua在表中使用nil
标记已删除的条目.如果将JSONinc null
转换为Lunatic nil
,则解码的对象将损坏.因此,cjson库使用轻量级的userdata类型表示null
/nil
.
Explanation: Lua uses nil
in tables to mark deleted entries. If JSONinc null
s were converted to Lunatic nil
s, the decoded objects would be corrupt. Therefore, the cjson lib uses a lightweight userdata type to represent null
/nil
.
您的"call_data"具有一个"date_created"字段,该字段为null,这会导致错误.
Your 'call_data' has a 'date_created' field that is null - that causes the error.
有趣的是,与Lua一样,Redis不会存储nil/null值,因此您必须忽略null值或在Redis中使用特殊值来标记它们.
The funny thing is that Redis, like Lua, will not store a nil/null value, so you'll have to either ignore null values or use a special value in Redis to flag them.
假设您将忽略它们,这是解决问题的一种方法:
Assuming you'll be ignoring them, here's one way around it:
local call_data = cjson.decode(ARGV[1])
local other_data = cjson.decode(ARGV[2])
local data = {}
local next = next
local null = cjson.null
local populate_data = function(source)
if next(source) == nil then
return
end
for property,value in pairs(source) do
if value ~= null then
redis.call('HSET', KEYS[2], property, value)
end
end
end
populate_data(call_data)
populate_data(other_data)
此外,一个小的优化将是批量更新,如下所示:
Also, a small optimization would be to batch the updates, like so:
local payload = {}
for property,value in pairs(source) do
if value ~= null then
table.insert(payload, property)
table.insert(payload, value)
end
end
redis.call('HSET', KEYS[2], unpack(payload))
P.S.如果需要,请查看我编写的 ReJSON -它旨在帮助您解决出现的问题您正在尝试做.
P.S. if you want, look at ReJSON that I wrote - it is designed to help with what it appears that you're trying to do.
这篇关于如何在Redis的Lua cjson中检查nil/null?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!