Monday, June 3, 2024
 Popular · Latest · Hot · Upcoming
127
rated 0 times [  129] [ 2]  / answers: 1 / hits: 8975  / 10 Years ago, thu, march 13, 2014, 12:00:00

I had a multiple chanel like this



client.HMSET('live:user:1', {
a: 1,
b: 1
});
client.HMSET('live:user:2', {
a: 2,
b: 2
});
client.HMSET('live:user:3', {
a: 3,
b: 3
});

client.HMSET('otherchanel:user:4', {
a: 4,
b: 4
});
client.HMSET('otherchanel:user:5', {
a: 5,
b: 5
});
client.HMSET('otherchanel:user:6', {
a: 6,
b: 6
});


How can i select all values by key pattern live:*? I need it to retern JSON object to my client app like this:



[{user:1, a:1, b:1}, {user:2, a:2, b:2}, {user:3, a:3, b:3}]

More From » node.js

 Answers
-1

It's simple, but you have to also fetch all the keys and combine them. I suggest using async to make the calls asynchronous:



function getAllUsersInChannel_suboptimal(channelName, functionCallback) {
client.keys(channelName + :user:*, function(err, userKeys) {
if (!err) {
async.map(userKeys,
function(userKey, callback) {
client.hgetall(userKey, function(err, user) {
if (!err) {
callback(null, user);
}
else {
callback(err);
}
});
},
function(err, userList) {
if (!err) {
functionCallback(null, userList);
}
else {
functionCallback(err);
}
});
}
else {
functionCallback(err);
}
});
}


Using a pattern match can drastically reduce performance even on medium sized databases. I suggest you also index the id's of the users using a set.



Create the counter key if it does not exist and set its value to 0:



SETNX <channel_name>:user:counter 0


When you add a new user, first increment the counter key, which also fetches its value:



INCR <channel_name>:user:counter => <new_id>


This will yield the new id for the user. Now you have to save a new member in the user:index set like so:



SADD <channel_name>:user:index <new_id>


You can now add the new user key like so:



HMSET <channel_name>:user:<new_id> <list of values>


To fetch data for all users you would first get a the list of existing users like so:



SMEMBERS <channel_name>:user:index => <list of all user ids>


For each id you would have to fetch the hash values:



asynchronous each <list of all user ids> as <user_id>
HGETALL channel_name>:user:<user_id> => all values of key
end asynchronous each


In Node.js, considering that you've already used the techniques above to index users, you retrieve all users in a channel using something like this:



function getAllUsersInChannel_optimal(channelName, functionCallback) {
client.smembers(channelName + :user:index, function(err, userIds) {
if (!err) {
async.map(userIds,
function(userId, callback) {
client.hgetall(channelName + :user: + userId, function(err, user) {
if (!err) {
callback(null, user);
}
else {
callback(err);
}
});
},
function(err, userList) {
if (!err) {
functionCallback(null, userList);
}
else {
functionCallback(err);
}
});
}
else {
functionCallback(err);
}
});
}

[#46896] Wednesday, March 12, 2014, 10 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
diamondlauryna

Total Points: 386
Total Questions: 93
Total Answers: 103

Location: South Korea
Member since Fri, Sep 11, 2020
4 Years ago
diamondlauryna questions
;