如何在Redis的Lua cjson中检查nil / null?

时间:2018-10-19 07:58:25

标签: json redis lua cjson

我有一个带代码块的lua脚本,如下所示:

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运行脚本时:-

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 

1 个答案:

答案 0 :(得分:2)

TL; DR表示ks返回的值,请使用cjson.decode()与JSON的cjson.null值进行比较。

说明:Lua在表中使用null标记已删除的条目。如果将JSONinc nil转换为Lunatic null,则解码的对象将损坏。因此,cjson库使用轻量级的userdata类型表示nil / null

您的“ call_data”具有一个“ date_created”字段,该字段为空-导致错误。

有趣的是,与Lua一样,Redis不会存储nil / null值,因此您必须忽略null值或在Redis中使用特殊值来标记它们。

假设您将忽略它们,这是解决问题的一种方法:

nil

此外,一个小的优化将是批量更新,如下所示:

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)

P.S。如果您愿意,请看一下我写的ReJSON-它旨在帮助您解决您尝试做的事情。