如何用Redis Lua脚本结合hget命令按月汇总哈希键值并解决报错
解决Redis Lua脚本汇总哈希键值的问题
Hey, let's fix your Lua script step by step. The error you're seeing isn't about tostring not working—it's actually a variable scope issue in Lua, plus a small problem handling missing keys. Let's break it down:
1. 为什么会出现"unexisting global variable 'dd'"错误?
在你原来的脚本里,local dd是定义在if i < 10的代码块内部的。Lua的局部变量只在它被声明的代码块内有效,所以当执行到else分支时,dd根本没被定义,Lua会把它当成全局变量去查找,自然就报错了。这和tostring的功能无关哦。
2. 修复作用域问题 + 处理不存在的键
还有一个隐藏问题:如果某个日期键(比如20180130)在哈希表里不存在,redis.call('hget')会返回nil,直接把nil和数字相加会抛出新的错误,所以我们需要把不存在的键值默认转为0。
下面是修正后的sumkey.lua脚本:
local mon = ARGV[1] local sumkey = 0 local dd -- 把dd的声明提到if/else块外面,让所有分支都能访问到 for i = 1,31 do if i < 10 then dd = '0' .. tostring(i) else dd = tostring(i) end local current_val = redis.call('hget', KEYS[1], mon .. dd) -- 把nil转为0,确保计算时都是数字类型 sumkey = sumkey + (tonumber(current_val) or 0) end return sumkey
3. 正确执行脚本的命令
你之前执行脚本时忘记传必填参数了:
KEYS[1]:哈希表的键名(也就是SiteID:TotalCnt)ARGV[1]:要汇总的月份前缀(也就是201801)
正确的执行命令注意逗号前面有空格,用来分隔键和参数:
redis-cli -n 2 --eval sumkey.lua SiteID:TotalCnt , 201801
用你的测试数据验证
基于你设置的测试数据:
hmset SiteID:TotalCnt 20180101 10 20180102 2 20180103 5 20180120 10 20180131 30 20180205 20 20180210 5
执行修正后的脚本会返回10+2+5+10+30 = 57,也就是所有1月份键值的总和。
额外优化(可选)
如果想让脚本适配所有月份(不止31天的月份),可以添加逻辑判断对应月份的天数,比如2018年2月只循环到28天。不过这个是进阶优化,你的核心问题已经可以通过上面的修改解决啦。
内容的提问来源于stack exchange,提问作者bstar
相关产品推荐
相关产品推荐

