Michael Joseph Aubry
Michael Joseph Aubry

Reputation: 13422

Turn redis keys into javascript object?

I want to grab all the users from redis and pass it into my template.

What I am getting returned is an array like ['users:nick','users:mike']

I dont want to have to regex it, I would like to take the usernames and store it inside an array of objects [{username: 'nick'}]

redisSessionClient.keys("users:*", function(err, users) {
  if(err) {
    console.log(err);
    return;
  }

  for (i = 0; i < users.length; i++) {
    console.log(users[i])
  }

  res.render('chat', req.user);
});

I think I am a little confused with the redis way of doing things and syntax, so I am open for any suggestions.

Upvotes: 0

Views: 546

Answers (2)

djfdev
djfdev

Reputation: 6037

Redis uses strings as keys, so you just have to parse it:

redisSessionClient.keys('users:*', function(err, users) {
  var newArray = users.map(function(user) {
    return {
      username: user.split(':')[1]
    };
  });

  // newArray is what you wanted
});

Edit: seeing as this answer was accepted, I'll echo everyone's concerns about why using keys is inappropriate in production.

To query all the keys in Redis takes O(n) time, where n is the total number of keys you have stored. So if you have 1 million keys but only 200k of those keys have the users: prefix, you've essentially wasted 800k operations by using keys to get a list of all your usernames. This is an expensive operation that could have major performance impacts on your production application.

Matias' answer is a good example of how to use these commands if you have a set of all your usernames.

Upvotes: 1

Mat&#237;as Fidemraizer
Mat&#237;as Fidemraizer

Reputation: 64923

What you need is storing all nicknames in a set and just call smembersor sscan on the set key.

Whenever you register a new user, you'll need to both add your users wherever you want and also add the nickname as is to a set called, for example, users:names.

That is, if you call smembers or sscan using the following code, you'll get things done right:

redisSessionClient.smembers('users:names', function(err, userNames) {
  var newArray = userNames.map(function(userName) {
    return {
      username: userName
    };
  });
});

At the end of the day, you need to change your mind when working with Redis: if you need to get some property values of some entity, then you'll need to store these values separately and get them. It's like working with raw indexes.

Anyway, take a look at scan-based commands to go further and even get a better approach. In simple cases and not that big databases, smembers should be fine.

Upvotes: 2

Related Questions