如何用Lua实现RedisJSON嵌套路径不存在时自动创建并执行NUMINCRBY?
用Lua脚本实现RedisJSON嵌套路径的安全递增(自动补全缺失结构)
直接上可用的Lua脚本,完美解决你遇到的问题:
local key = ARGV[1] local path = ARGV[2] local increment = tonumber(ARGV[3]) -- 先尝试执行递增,失败再处理缺失结构 local res = redis.call('JSON.NUMINCRBY', key, path, increment) -- 捕获路径/键不存在的错误 if type(res) == 'table' and res.err then -- 拆分路径节点,去掉开头的点前缀 local segments = {} local cleaned_path = path:gsub('^%.', '') for seg in string.gmatch(cleaned_path, '[^%.]+') do table.insert(segments, seg) end local current_path = '' -- 逐级检查并创建缺失的结构 for i, seg in ipairs(segments) do current_path = current_path .. '.' .. seg local exists = redis.call('JSON.GET', key, current_path) if not exists then -- 最后一个节点初始化为0,中间节点创建空对象 local val = (i == #segments) and 0 or '{}' redis.call('JSON.SET', key, current_path, val) end end -- 结构补全后再次执行递增操作 res = redis.call('JSON.NUMINCRBY', key, path, increment) end return res
脚本核心特性
- 原子性保障:Redis将整个Lua脚本作为单个原子操作执行,完全适配多线程环境,不会出现并发下的结构不一致问题。
- 高效容错:先尝试原生递增操作,仅在报错时才触发结构创建,避免不必要的性能消耗。
- 智能补全:自动拆分目标路径,从根节点到叶子节点逐级检查,中间缺失的节点创建空JSON对象,最终数值节点初始化为0,确保递增操作能正常执行。
使用方式
你可以直接在Redis客户端用EVAL命令调用:
EVAL "这里粘贴上述Lua脚本内容" 0 "KEY" ".PATH1.COUNT" 5.0
或者将脚本保存为文件(比如incr_json.lua),通过redis-cli加载执行:
redis-cli --eval incr_json.lua , "KEY" ".PATH1.COUNT" 5.0
注意:命令中的逗号不能省略,它代表未指定Redis键参数(所有参数通过ARGV传递)。
测试验证
- 当
KEY完全不存在时,执行后会生成{"KEY": {"PATH1": {"COUNT": 5.0}}} - 当
KEY存在但PATH1不存在时,会自动创建PATH1对象并将COUNT设为5.0 - 当
COUNT已有值时,与原生JSON.NUMINCRBY行为一致,直接执行递增操作
内容的提问来源于stack exchange,提问作者Josh
相关产品推荐
相关产品推荐

