Node Redis Set Commands

08.29.2021

Intro

Sets are lists filled with unique items. The set data type is helpfuly when you want to work with unique data types, thus they help with features where you want to easily deuplicate values. In this article, we will learn how to work with sets in Redis and Nodejs.

Setting up Redis

For setting up Redis, I would recommend using a service for you in prod. Azure for example, has a great redis service that scales easily. However, you will want to learn redis and eventually how to scale it yourself. This will help with debugging cloud services or eventually, saving money and not using them.

We will start our intro to redis via using docker compose. Create a docker-compose.yml file and add the following.

version: "3.2"
services:
  redis:
    image: "redis:alpine"
    command: redis-server
    ports:
      - "6379:6379"
    volumes:
      - $PWD/redis-data:/var/lib/redis
      - $PWD/redis.conf:/usr/local/etc/redis/redis.conf
    environment:
      - REDIS_REPLICATION_MODE=master

Ensure you have docker installed and run

docker-compose up

Installing Redis Modules

There are two modules I see often used in nodejs. I will tend towards ioredis as it has built in support for promises and many other features in redis.

npm install ioredis

Writing the Code

Let's open up a new file, index.js and go through many of the common commands you will used with lists in redis.

Set Data Type

We can create a Set and add a value to the set using the following. The example below is similar to creating a unique list so:

const users = ["user1"]
// Set Add
await redis.sadd("users", "user1")

We can also set multiple keys by adding more parameters. Also notice that we duplicate the 'user1' key, but the set will only add this key once.

// Set Add
await redis.sadd("users", "user1", "user2", "user1")

We can get the memebrs of a set using the SMEMBERS command.

// Set Members
const result = await redis.smembers("users")
console.log(result) //output: ["user1", "user2"]

For each of the examples below, I will use the following template to run all the commands. Here is my full index file. We will just replace the commands each time.

const Redis = require("ioredis")

const redis = new Redis({})

async function main() {
    // Hash Set
    await redis.hset("users", "user1")

    // Set Members
    const result = await redis.smembers("users")
    console.log(result) //output: ["user1"]
}

(async () => {
    await main()
})()

Set Cardinality (Size)

If we want to get the size of our set, we can use scard.

// Set Cardinaility
const result = await redis.scard("users")
console.log(result) // output: 2

Set Difference

We can get the difference or the values that are not in both sets using the sdiff command. This can be helpful for tracking usage metrics.

await redis.sadd("users-feature1", "user1", "user2")
await redis.sadd("users-feature2", "user1")

// Set Difference
const result = await redis.sdiff("users-feature1", "users-feature2")
console.log(result) // output: ["user2"]

Set Intersection

Similar to above, we can get the intersection between two sets, the values that are in both sets, using the SINTER command.

await redis.sadd("users-feature1", "user1", "user2")
await redis.sadd("users-feature2", "user1")

// Set Intersection
const result = await redis.sinter("users-feature1", "users-feature2")
console.log(result) // output: ["user1"]

Set Union

Keeping with the theme of set operations, we can take the union of two sets, returning a combination of sets, using the SUNION command.

await redis.sadd("users-feature1", "user1", "user2")
await redis.sadd("users-feature2", "user1", "user3")

// Set Union
const result = await redis.sunion("users-feature1", "users-feature2")
console.log(result) // output: ["user1", "user2", "user3"]

Set Is Member and Multiple is Members

We can check if a key is a member of a set using the SISMEMBER command.

await redis.sadd("users", "user1", "user2")

// Set Is Member
const result = await redis.sismember("users", "users1")
console.log(result) // output: true

We can check multiple members (if you use redis 6 or later) with the SMISMEMBER which means Set Multiple Is Member.

await redis.sadd("users", "user1", "user2")

// Set Multiple Is Member
const result = await redis.sismember("users", "users1", "user2", "user3")
console.log(result) // output: [true, true, false]

Set Members

To get a list of all members, we can use the SMEMBERS command.

await redis.sadd("users", "user1", "user2")

// Set Members
const result = await redis.smembers("users")
console.log(result) // output: ["user1", "user2"]

Set Remove

We can remove a member from one set to another using the SREM command.

await redis.sadd("users", "user1", "user2")

// Set Remove
await redis.srem("users", "user1")
const result = await redis.smembers("users")
console.log(result) // output: ["user2"]