Redis Hashmaps or Hashes example in Node.js

I always used Redis as plain Hashmap where keys and values are just strings. Slowly I forgot Redis supports a couple data types (Lists, Sets, Sorted Sets, Hashes) until one of our Real-time machine learning prediction application gave trouble due to my bad design decision.

Let me give you some context about our application so that you can relate to the problem. We built a machine learning model which basically predicts whether a user will buy a car or not if yes then which car based on the user activity pattern on our Sites/Apps. Whenever a user visits our site/App we calculate user score on each car he/she interested. For that basically, we choose around 60 different features. So, Whenever a user visits our Site/App or doing an important event we calculate his/her score.

Some of the users visit often and do a lot of research so they have a lot of history under their belt for those users calculating the score and features aggregations often doesn’t make any sense. We use these aggregations in a couple of other places(other machine learning models & etc.) too. So we thought let’s put users activity aggregations with respect to features in Redis for some time. Here I did all the wrong things. I stored each feature aggregation of a user as a key, value pair.

Example:
Let's say user A did x thing 5 times, y thing 8 times, z thing 3 times. I stored it as
Key             | Value
------------------------
A_x             | 5
A_y             | 8
A_z             | 3

Because of this for every frequent user, I am creating 60 insert requests. At the same time whenever this application get hit to calculate the score for a user it will check whether feature values(aggregations) are available in cache or not so for this purpose also I am creating 60 concurrent get requests per user. Due to this Cache(Redis) become a bottleneck.

After doing bit googling I realized Hashes are the good fit for this use case. When I started implementing the solution I faced a little problem due to lack of code examples for hmset, hmget, hgetall in Node.js.

Below picture give you a clear idea about Hashes

Without wasting much time let’s take a small example and implement code for it.

Let’s say you want to build a small program which will have below 3 functionalities.
1. The user can add an animal or bird and its sound.
2. The user can ask to display all animals/birds and their respective sounds.
3. or specific animal/bird sound.

I hope you already have Redis Nodejs package installed. If not please install using below command

npm install redis

So it means sometimes we need to show all animal sounds or bird sounds and sometimes we need a specific animal or bird sound. Here it makes sense to use Redis Hashes. Please find example code below

Whenever we need to store we need to give a hash(key), subkey and value which we need to store w.r.t subkey.

Example Node.js Code:
---------------------
redisClient.hmset('Animal', {'Dog' : 'wuff wuff'}, (err, reply) => {
      if(err) {
        console.error(err);
      } else {
        console.log(reply);
      }
    });
Example Redis Commands:
----------------------
127.0.0.1:6379> hmset Animal Dog "wuff wuff"

Here Animal is Hash(key), Dog is subkey and value is wuff wuff. The data will be stored at Redis end like below

127.0.0.1:6379> keys *
1) "Animal"

See here the key is our Hash which is Animal. Data in the hash stored like below

127.0.0.1:6379> hgetall Animal
1) "Dog"
2) "wuff wuff"

Here Dog is our subkey and wuff wuff is our value. You can get all the data in the key through hgetall command.

Example Node.js Code:
---------------------
redisClient.hgetall(category, (err, object) => {
      if(err) {
        console.error(err);
      } else {
        console.log(object);
      }
    });

If you want specifically the subkey value here it is Dog then you need to use hmget command. To hmget command, we need to give the key and subkey as input so that it will give us the value corresponding to that subkey(Dog).

127.0.0.1:6379> hmget Animal Dog
1) "wuff wuff"
Example Node.js Code:
---------------------
redisClient.hmget(category, speciesName, (err, object) => {
      if(err) {
        console.error(err);
      } else {
        console.log(object);
      }
    });

You will find this example code at my GitHub repository.

If you need some more examples for Redis and Nodejs you will find here.

Peace. Happy Coding.

Related Post