Reputation: 19772
In Redis, say I have an ordered set of IDs (which are scored by a timestamp):
(name of ordered set) someobject:media
Member | Score
1 1442784376400
2 1442784376420
3 1442784376450
Each member is an ID of a hash (like this):
media:1 { 'name': 'something', 'timestamp': '1442784376400 }
media:2 { 'name': 'somethingelse', 'timestamp': '1442784376420' }
// and so forth
Is there an atomic operation that would allow me to get all the hashes for the members of someobject:media
?
I'm using Node Redis, which in theory provides all the operations that redis-cli provides (as one would expect).
So far, my only thought is to loop through everything, like this:
client.zrevrange(['someobject:media', 0, -1], (err, res) => {
let promises = res.map(mediaId => {
return new Promise((resolve, reject) => {
client.hgetall('media:' + mediaId, (err, res) => {
resolve(res);
});
});
});
Promise.all(promises).then(result => {
// do something with the "media" hashes
});
});
My gut tells me there is some sort of atomic "join" type operation that Redis provides, but maybe I'm wrong. The above method looks entirely inefficient.
In other words, I want to join on all media:<id>
from the ordered set of someobject:media
. Is this possible?
Upvotes: 3
Views: 1050
Reputation: 10907
You can use one sort command, but you must explicitly specify all hash fields names. For your example, it would be:
sort someobject:media get media:*->name get media:*->time
1) "something"
2) "1442784376400"
3) "somethingelse"
4) "1442784376420"
5) (nil)
6) (nil)
For easier reading of the answer, you can add get #
to get the index as well:
sort someobject:media get # get media:*->name get media:*->time
1) "1"
2) "something"
3) "1442784376400"
4) "2"
5) "somethingelse"
6) "1442784376420"
7) "3"
8) (nil)
9) (nil)
Upvotes: 0
Reputation: 6377
I don't think sort
works with hashes. You can use multi
mode and it will still be efficient. Multi is more typical in redis than something like a join. Something like this:
client.zrange("members", 0, 100, function (err, replies) {
var m = client.multi()
replies.forEach(function(item) {
m.hgetall(item);
});
m.exec(function(err, hashes) {
});
});
Upvotes: 4
Reputation: 106037
My Redis is suuuuper rusty, but I think you want to use the (confusingly-named) SORT
command for this. Something like:
SORT someobject:media BY nosort GET media:*
I've not used node_redis but I think this translates to something like this:
client.sort([ "someobject:media", "by", "nosort", "get", "media:*" ], (err, res) =>
// ...
});
Upvotes: 1