使用Lua触发Redis HMSET操作。

我需要使用 Redis Lua 脚本调用 Redis 的 HMSET。这里是咖啡脚本:

redis = require("redis")
client = redis.createClient();

lua_script = "\n
-- 这里有问题\n
local res = redis.call('hmset', KEYS[1],ARGV[1])\n
print (res)\n
-- 创建二级索引\n
--\n
--\n
return 'Success'\n
"

client.on 'ready', () ->
  console.log 'Redis is ready'
  client.flushall()
  client.send_command("script", ["flush"])

  args = new Array(3)

  args[0] = '1111-1114'
  args[1] = 'id'
  args[2] = '111'
  callback = null
  #client.send_command("hmset", args, callback) # 这个是可以工作的

  client.eval lua_script, 1, args, (err, res) ->
    console.log 'Result: ' + res

什么是调用 LUA 脚本中的 HMSET 的正确语法/模式? 顺便说一句 - 我知道 redis.HMSET 命令。

点赞
用户204011
用户204011

首先,您确定在您的 CoffeeScript Redis 库中正确使用 eval 吗?您显然传递了三个参数:脚本、键数和数组。我怀疑这不是它的工作方式。如果这是 node_redis,那么一切或一无所有必须在数组中,所以尝试一下:

args = new Array(5)

args[0] = lua_script
args[1] = 1
args[2] = '1111-1114'
args[3] = 'id'
args[4] = '111'
callback = null

client.eval args, (err, res) ->
  console.log 'Result: ' + res

(可能有更好的语法,但我不知道CoffeeScript。)

其次,在这个例子中,您正在尝试 HMSET 单个字段/值对:

HMSET lua_script 1111-1114 id 111

实际上,您可以在此处将 HMSET 替换为 HSET,但让我们首先使其工作。

在这一行中:

local res = redis.call('hmset', KEYS[1], ARGV[1])

您只添加了带有哈希的键和字段的 HMSET,因此需要添加作为第二个参数的值:

local res = redis.call('hmset', KEYS[1], ARGV[1], ARGV[2])

这将使您的示例工作,但是如果您希望实际上设置 多个 字段(这是 MHSET 的目标),例如:

HMSET lua_script 1111-1114 id 111 id2 222

则在 CoffeeScript 中,您将编写:

args = new Array(7)

args[0] = lua_script
args[1] = 1
args[2] = '1111-1114'
args[3] = 'id'
args[4] = '111'
args[5] = 'id2'
args[6] = '222'
callback = null

client.eval args, (err, res) ->
  console.log 'Result: ' + res

…但现在 ARGV 中有 四个 元素要传递给 Lua 中的redis.call。实际上,您必须传递 ARGV所有 元素,这称为 Lua 中的 unpack()

local res = redis.call('hmset', KEYS[1], unpack(ARGV))

使用 unpack() 的唯一问题是,如果 ARGV 中的元素很多(数千个),则可能会崩溃,因为它会溢出堆栈,在这种情况下,您应该在 Lua 脚本中使用循环在 ARGV 的片段上调用 HMSET,但现在您可能不用担心这个问题...

2013-08-26 15:48:30