MongoDB $addToSet Operator: A Step-by-Step Guide for Node.js

In MongoDB, we use arrays to store different types of values ​​like strings, numbers, objects, and even arrays. Now if we want to add a new element to an array present inside the documents, we usually use the $push operator which has a problem. It just adds the value ​​to the array without checking for duplicates which leads to duplicates in the array.

So here comes the $addToSet operator which works like $push but also checks for duplicates first, so if a duplicate value exists while adding a new value to the array, the new value will not be added. Let’s learn more about this operator by demonstrating it in a real Node.js project.

MongoDB $addToSet Operator

MongoDB $addToSet operator adds a value to an array field if it does not exist. If the value is already present, $addToSet does nothing and the array remains unchanged.

Syntax:

{ $addToSet: { <field>: <value> } }

If the specified <field> does not exist, this operator will create it with the <value> passed. Also, the $addToSet operator cannot be used for non-array fields.

The $addToSet by itself can only add one element at a time. Even if you pass an array it will added as a single element. To add each element of the value separately we have to group it with the $each. Click here to learn how to do that.

Using $addToSet Operator in Node.js

Let’s create a Node.js application to be able to demonstrate the usage of the $addToSet operator with a clear example. Here are the steps below to get you started.

Step 1: Create a Node.js project directory and get into it:

mkdir nodeaddToSet
cd nodeaddToSet

Step 2: Initialise NPM using the below command:

npm init -y

Once you pass this command, you should see a package.json file created in your project directory.

Step 3: Create the entry point JavaScript file:

touch app.js

Step 4: Install Express with Mongoose for working with MongoDB database:

npm i express mongoose

Are Mongoose and MongoDB different? Click here to know.

Step 5: Import packages inside app.js:

const express = require('express');
const app = express();
const mongoose = require('mongoose');

Step 6: Connect with the local MongoDB database using Mongoose:

mongoose.connect('mongodb://localhost:27017/farmAndDairyDB', { useNewUrlParser: true, useUnifiedTopology: true })
    .then(() => {
        console.log(`YAY! CONNECTED TO MONGO!`);
    })
    .catch((err) => {
        console.log(`UH OH! MONGO CONNECTION ERROR!`);
        console.log(err);
    })

Step 7: At the end of the app.js file, set up a localhost port for the app server to listen:

app.listen(8000, () => {
    console.log('Connected to PORT 8000...');
})

Step 8: Next, create a new directory named models in our project directory:

mkdir models

Step 9: Create a new file inside the directory named harvests.js, or anything you’d like:

touch models/harvests.js

Step 10: Import Mongoose here as well to create a schema for our farm and dairy products and the associated model:

const mongoose = require('mongoose');

const productsSchema = new Schema({
    name: {
        type: String,
        required: true
    },
    price: {
        type: Number,
        required: true,
        min: 0
    },
    category: {
        type: String,
        lowercase: true,
        enum: ['fruit', 'vegetable', 'dairy']
    },
});

const Product = mongoose.model('Product', productsSchema);

Step 11: To use the $addToSet operator on our documents, add a few documents:

{ "_id" : ObjectId("6054f4ba0e761c066439114b"), "name" : "Fairy Eggplant", "price" : 1, "category" : "vegetable", "__v" : 0 }
{ "_id" : ObjectId("6054f4ba0e761c066439114c"), "name" : "Organic Goddess Melon", "price" : 4.99, "category" : "fruit", "__v" : 0 }
{ "_id" : ObjectId("6054f4ba0e761c066439114d"), "name" : "Organic Mini Seedless Watermelon", "price" : 3.99, "category" : "fruit", "__v" : 0 }
{ "_id" : ObjectId("6054f4ba0e761c066439114e"), "name" : "Organic Celery", "price" : 1.5, "category" : "vegetable", "__v" : 0 }
{ "_id" : ObjectId("6054f4ba0e761c066439114f"), "name" : "Chocolate Whole Milk", "price" : 2.69, "category" : "dairy", "__v" : 0 }
{ "_id" : ObjectId("6054f4ba0e761c066432875g"), "name" : "Fresh Orange Juice", "price" : 1.52, "category" : "fruit", "__v" : 0 }

Step 12: Using the $addToSet operator:

Let’s say we updated our Mongoose schema after we created and saved these documents. Now, we also want to add “juice” to our category key. So, for the last document, which is “Fresh Orange Juice”, we want to keep the “fruit” value but also add the “juice” value to that array.

To do so, we will simply use the $addToSet operator with update():

Product.update({
    "$addToSet": { "category": "juice" }
}, function (err, doc) {
    if (err) throw error;
    console.log(`Category updated for: ${doc.name}`);
    console.log(doc);
});

Output:

This is what our console prints.

Category updated for Fresh Orange Juice

{
    "_id" : ObjectId("6054f4ba0e761c066432875g"), 
    "name" : "Fresh Orange Juice", 
    "price" : 1.52, 
    "category" : [
        "fruit", 
        "juice"
    ], 

This way we have successfully used the $addToSet operator in MongoDB with the help of Mongoose in a Node.js application.

Summary

In short, MongoDB $addToSet operator is used to add a value to array fields in the document on the condition that the value being added should not already exist. Also if the field itself doesn’t exist, it creates it with the given value. And if an array we want to add an element in is nested within an object inside an array field, we can use dot notation to target it. Also, we can use the $each modifier with $addToSet to add multiple unique elements to an array field.

Reference

https://www.mongodb.com/docs/manual/reference/operator/update/addToSet/

Aneesha S
Aneesha S
Articles: 171