Kirzilla
Kirzilla

Reputation: 16596

Is there MGET analog for Redis hashes?

I'm planning to start using hashes insead of regular keys. But I can't find any information about multi get for hash-keys in Redis wiki. Is this kind of command is supported by Redis?

Thank you.

Upvotes: 59

Views: 40380

Answers (5)

Itamar Haber
Itamar Haber

Reputation: 49962

No MHGETALL but you can Lua it:

local r = {}
for _, v in pairs(KEYS) do
  r[#r+1] = redis.call('HGETALL', v)
end

return r

Upvotes: 12

Fabian Jakobs
Fabian Jakobs

Reputation: 29153

Redis has a HMGET command, which returns the values of several hash keys with one command.

Upvotes: -4

rjp
rjp

Reputation: 1958

If SORT let you use multiple GETs with the -> syntax, and all your hashes had the same fields, you could get them in a bulk reply by putting their names into a set and sorting that.

  SORT names_of_hashes GET *->field1 *->field2 *->field3 *->etc

But it doesn't look like you can do that with the hash access. Plus you'd have to turn the return list back into hashes yourself.

UPDATE: Redis seems to let you fetch multiple fields if you name your hashes nicely:

redis> hset hash:1 name fish
(integer) 1
redis> hset hash:2 name donkey
(integer) 1
redis> hset hash:3 name horse
(integer) 1
redis> hset hash:1 type fish
(integer) 1
redis> hset hash:2 type mammal
(integer) 1
redis> hset hash:3 type mammal
(integer) 1
redis> sadd animals 1
(integer) 1
redis> sadd animals 2
(integer) 1
redis> sadd animals 3
(integer) 1
redis> sort animals get # get hash:*->name get hash:*->type
1. "1"
2. "fish"
3. "fish"
4. "2"
5. "donkey"
6. "mammal"
7. "3"
8. "horse"
9. "mammal"

Upvotes: 12

kmerenkov
kmerenkov

Reputation: 2889

You can query hashes or any keys in pipeline, i.e. in one request to your redis instance. Actual implementation depends on your client, but with redis-py it'd look like this:

pipe = conn.pipeline()
pipe.hgetall('foo')
pipe.hgetall('bar')
pipe.hgetall('zar')
hash1, hash2, hash3 = pipe.execute()

Client will issue one request with 3 commands. This is the same technique that is used to add multiple values to a set at once.

Read more at http://redis.io/topics/pipelining

Upvotes: 68

Mikushi
Mikushi

Reputation: 3351

There is no command to do it on one shot, but there is a way to do it "nicely", using a list (or sorted set) where you would store you hashKeys, and then retrieve them as bulk using multi.

In PHP:

$redis->zAdd("myHashzSet", 1, "myHashKey:1");
$redis->zAdd("myHashzSet", 2, "myHashKey:2");
$redis->zAdd("myHashzSet", 3, "myHashKey:3");

$members = $redis->zRange("myHashzSet", 0, -1);
$redis->multi();
foreach($members as $hashKey) {
    $redis->hGetAll($hashKey);
}
$results = $redis->exec();

I recommand using a sorted set, where you use the score as an ID for your hash, it allows to take advantages of all score based command.

Upvotes: -1

Related Questions