2013-08-25 2 views
0

Мне нужно позвонить Redis HMSET с помощью скрипта Redis Lua. Вот сценарий для кофе:Trigger Redis HMSET с LUA

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

lua_script = "\n 
-- here is the problem\n 
local res = redis.call('hmset', KEYS[1],ARGV[1])\n 
print (res)\n 
-- create secondary indexes\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) # this works 

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

Каков правильный синтаксис/шаблон для вызова HMSET в сценарии LUA? BTW - Я знаю команду redis.HMSET.

+0

Я новый для использования lua в redis, но вам может понадобиться использовать 'unpack'. Я использую этот код, который я опубликовал [здесь] (http://codereview.stackexchange.com/questions/30195/redis-rate-limiting-in-lua), хотя я использую его для 'HMGET'. – JesseBuesking

+0

BTW Это 'Lua' не 'LUA' –

ответ

0

Во-первых, вы уверены, что используете eval в своей библиотеке CoffeeScript Redis? Вы, по-видимому, передаете три аргумента: скрипт, количество ключей и массив. Я подозреваю, что это не так, как это работает. Если это 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 на здесь H Установите, но давайте сделать его работу первым.

В этой строке:

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 перейти к redis.call в Lua. На самом деле вы должны пройти всех элементов ARGV, и это называется unpack() в Lua:

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

Единственная проблема с использованием unpack() в том, что если у вас есть реальных много элементов в ARGV (тыс), он может сломаться, потому что он переполнит стек, и в этом случае вы должны использовать цикл в сценарии Lua для вызова HMSET на срезах ARGV, но на данный момент вам, вероятно, не стоит беспокоиться об этом ...