Node-redis: multi.hmget not working when passing in an array of hash keys.

Created on 3 Mar 2013  路  9Comments  路  Source: NodeRedis/node-redis

Hi,
I am using the latest version of node-redis on npm (0.8.2 https://npmjs.org/package/redis),
Anyway when I call the below commands everything is peachy:

redisClient.hmget('{key}', ['{hashkey1}', '{hashkey2}']) => [val1, val2]
redisClient.hmget('{key}', '{hashkey1}', '{hashkey2}') => [val1, val2]
multi.hmget('{key}', '{hashkey1}', '{hashkey2}') => [val1, val2]

But when I call hmget with multi and feed an array of keys as the second paramater (below), all I get back is null.

multi.hmget('{key}', ['{hashkey1}', '{hashkey2}']) => [null]

As this is all through my code, this is rather inconvenient, it would be great if you could fix this and update npm, as I will have to revert to an older version until this is fixed.

Cheers

bug fixed / done

Most helpful comment

@katopz this is a day or two late, but i was struggling with the same problem and ended up being able to use the spread operator to make this work properly.

client.hmget('hash key 2', ...['key 1', 'key 2'], function (err, reply)  {}

Hope that helps.

All 9 comments

Hi @Jezternz -- there are some multi parser bug fixes that should go out in the next version. This may be an instance of one of the bugs that #382 will fix. You could try your example with that PR to see if it fixes your issue.

multi.hmget('{key}', ['{hashkey1}', '{hashkey2}']) => [null]

Well, all the same for current moment. =(

The workaround is to use multi.hmget like that:
multi.hmget(['{key}', '{hashkey1}', '{hashkey2}'])

Ahh, yes, this is because the list is stringified. Multi isn't getting the same HMGET command parsing logic that you get without multi. See https://github.com/mranney/node_redis/blob/master/index.js#L968

This sort of thing is exactly one of the things I'm working on fixing in the refactor.

> c.multi().hmget("somehash", ["cat", "cow"]).exec(console.log)
send 127.0.0.1:6379 id 2: *1
$5
MULTI

send_command buffered_writes: 0  should_buffer: false
send 127.0.0.1:6379 id 2: *3
$5
hmget
$8
somehash
$7
cat,cow

send_command buffered_writes: 0  should_buffer: false
send 127.0.0.1:6379 id 2: *1
$4
EXEC

vs.

c.multi().hmget("somehash", "cat", "cow").exec(console.log)
send 127.0.0.1:6379 id 2: *1
$5
MULTI

send_command buffered_writes: 0  should_buffer: false
send 127.0.0.1:6379 id 2: *4
$5
hmget
$8
somehash
$3
cat
$3
cow

send_command buffered_writes: 0  should_buffer: false
send 127.0.0.1:6379 id 2: *1
$4
EXEC

I just ran into this and the following worked for me.

function getMultiFields(key, fields, callback) {
    var multi = redis.multi();
    multi.hmget.apply(multi, [key].concat(fields));
    multi.exec(callback);
}

Oh hey @barisusakli, fancy seeing you here. Your code worked for me. (In my case, I accidentally defaulted to using null instead of multi for the thisArg in .apply(). Changing it to multi fixed it up)

This is fixed in newer versions

So what final function look like? I saw

            it('returns strings for keys requested', function (done) {
                client.hmget('hash key 2', 'key 1', 'key 2', function (err, reply) {
                    assert.strictEqual(true, Array.isArray(reply));
                    assert.strictEqual(2, reply.length);
                    assert.strictEqual('val 1', reply[0]);
                    assert.strictEqual('val 2', reply[1]);
                    return done(err);
                });
            });

but not this anywhere

client.hmget('hash key 2', ['key 1', 'key 2'], function (err, reply)  {}

In my case ['key 1', 'key 2'] is need because it will be vary and I can't find the way to make it work.
Thanks

@katopz I was able to use the following pattern to accomplish what you are looking for:

  // set up multi
  var multi = client.multi();

  // add each key to pipe
  for(var i = 0; i < keys.length; i++) {
    multi = multi.hgetall(keys[i]);
  }
  // execute multi
  multi.exec(function (err, replies) {
    if(err) console.error(err);
    else console.log(replies);
  });

I hope this helps you!

@katopz this is a day or two late, but i was struggling with the same problem and ended up being able to use the spread operator to make this work properly.

client.hmget('hash key 2', ...['key 1', 'key 2'], function (err, reply)  {}

Hope that helps.

Was this page helpful?
0 / 5 - 0 ratings