Node.JS MongoDB: The Complete Guide
MongoDB and Node.JS: The Complete Guide

Node.JS MongoDB: The Complete Guide

Dead Simple Chat Team

Table of Contents

Dead Simple Chat offers prebuilt Chat that can be added in minutes to any app or website. Can be completely customized and offers powerful Chat API and SDK.

Part 1: This is part 1 of the 2-part series

In this guide we will explore in detail how we can use Node.JS with MongoDB, ranging from basic operations to aggregation.

Table of Contents

Installing Node.JS MongoDB Driver

Installing the MongoDB driver is very simple, just cd into your project directory and run

npm install mongodb@latest

Connecting to MongoDB

You can connect to a remote MongoDB instance or for development run a MongoDB instance locally using docker.

To launch a MongoDB instance in docker first pull the MongoDB docker image using the docker pull command.

docker pull mongo

To launch the docker container run the command docker run and forward the port 27017 from the container to the host machine.

docker run -d --name mymongo -p 27017:27017 mongo

Once MongoDB is running connect to your local mongo by importing the MongoDB driver

const { MongoClient } = require("mongodb");

const uri = "mongodb://localhost:27017"; // If you are using a cloud mongodb instance you replace it with your cloud connection string

const client = new MongoClient(uri);

The uri contains the MongoDB URI has the following format:

mongodb://[username:password@]host1[:port1][,...hostN[:portN]][/[defaultauthdb][?options]]

You can learn more about the MongoDB URI here:
https://www.mongodb.com/docs/manual/reference/connection-string/

Chat API Trusted by world’s biggest corporations | DeadSimpleChat
Chat API and SDk that supports 10 Million Concurrent Users. Features like Pre-Built turn key Chat Solution, Chat API’s, Customization, Moderation, Q&A, Language Translation.

Background

We will create a collection named books and insert and book document. The book document will look this:

{
  _id: ObjectId("63c56efb31fd431a23e9077d"),
  title: '1984',
  authors: [ { firstName: 'george', lastName: 'orwell' } ],
  genre: [ 'classic', 'science_fiction' ],
  published_date: ISODate("1949-06-08T04:00:00.000Z"),
  pages: 298,
  isbn_10: '1443434973',
  isb_13: '978-1443434973',
  reviews: [
    {
      rating: 5,
      created: ISODate("2023-01-03T05:00:00.000Z"),
      title: 'Must read',
      description: 'Every citizen with a brain or even an inquisitive mind should read this.',
      username: 'chris'
    },
    {
      rating: 3,
      created: ISODate("2022-11-09T05:00:00.000Z"),
      title: 'Great',
      description: "Great really enjoyed reading this book. It's not a 5 star bc it was dull at times",
      username: 'blaze'
    }
  ]
}
  • _id: autogenerated MongoDB ObjectID
  • title: title of the book
  • authors: array of authors, some books have multiple authors hence authors is an array
  • genre: array of genre the book belongs to
  • pages: count of the number of pages in the book
  • reviews: array of objects containing individual reviews of the book  

Create Documents: insertOne and insertMany

Once we have connected to the MongoDB instance, let's learn about inserting documents in MongoDB.

MongoDB is a NoSQL database, hence we can insert JSON objects directly into MongoDB.

insertOne

To insert one document in MongoDB you can use the insertOne method. This method inserts one document at a time.

const { MongoClient } = require("mongodb");

const uri = "mongodb://localhost:27017";

const client = new MongoClient(uri);

(async function () {
  try {
    const db = client.db("mydb");
    const doc = await db.collection("books").insertOne({
      title: "Where the Crawdads Sing",
      authors: [
        {
          firstName: "delia",
          lastName: "owens",
        },
      ],
      genre: ["literary_fiction"],
      published_date: new Date("Aug 14, 2018"),
      pages: 400,
      isbn_10: "0735219109",
      isb_13: "978-0735219106",
      reviews: [
        {
          rating: 5,
          created: new Date("Jan 8, 2023"),
          title: "Excelled read",
          description:
            "This is a very good read, I couldn’t put it down for a day until I finished the book.",
          username: "lora",
        },
        {
          rating: 3,
          created: new Date("Jan 8, 2020"),
          title: "Huge disappointment.",
          description:
            "After all the rave reviews I was expecting something exceptional but was completely underwhelmed.",
          username: "stacy",
        },
      ],
    });
    console.log(doc);
  } catch (ex) {}
})();

In the above code snippet, we used the client.db("mydb") to get the reference to a database named mydb.

In MongoDB, if the database with the name mydb doesn't exist then it will be created for us automatically.

Using the db.collection("books").insertOne method we inserted the document in the collection named books.

If the collection named books doesn't exist then MongoDB will automatically create a collection named books and insert our document into the collection.  

After we run this command the doc variable would contain the following data:

{
  acknowledged: true,
  insertedId: new ObjectId("63c1ba50274c034c847c97c9")
}

insertedId is the _id of our document, we can use this _id to retrieve the document from the collection.

insertMany

With the insertMany method you can insert multiple documents into the MongoDB collection in bulk.

To insert multiple documents, instead of one document we pass an array of documents to the insertMany method.

const { MongoClient } = require("mongodb");

const uri = "mongodb://localhost:27017";

const client = new MongoClient(uri);

(async function () {
  try {
    const db = client.db("mydb");
    const docsInserted = await db.collection("books").insertMany([
      {
        title: "To Kill a Mockingbird",
        authors: [
          {
            firstName: "harper",
            lastName: "lee",
          },
        ],
        genre: ["classic", "literary_fiction"],
        published_date: new Date("Jan 1, 1960"),
        pages: 336,
        isbn_10: "0446310786",
        isb_13: "978-0446310789",
        reviews: [
          {
            rating: 5,
            created: new Date("May 8, 2020"),
            title: "fairly straight-forward coming of age story",
            description:
              "It certainly does with me and I think the adjective “charm” may have been invented to describe the novel.",
            username: "stephen",
          },
          {
            rating: 4,
            created: new Date("Dec 9, 2020"),
            title: "If you haven't read this as an adult - pick it up today",
            description: "I think there's just one kind of folks. Folks.",
            username: "miranda",
          },
        ],
      },
      {
        title: "1984",
        authors: [
          {
            firstName: "george",
            lastName: "orwell",
          },
        ],
        genre: ["classic", "science_fiction"],
        published_date: new Date("June 8, 1949"),
        pages: 298,
        isbn_10: "1443434973",
        isb_13: "978-1443434973",
        reviews: [
          {
            rating: 5,
            created: new Date("Jan 3, 2023"),
            title: "Must read",
            description:
              "Every citizen with a brain or even an inquisitive mind should read this.",
            username: "chris",
          },
          {
            rating: 3,
            created: new Date("Nov 9, 2022"),
            title: "Great",
            description:
              "Great really enjoyed reading this book. It's not a 5 star bc it was dull at times",
            username: "blaze",
          },
        ],
      },
    ]);
    console.log(docsInserted);
  } catch (ex) {}
})();

In the above code snippet we have inserted two documents in the books collection.

After inserting the documents in the books collection the command returns the following response, which we store in the docsInserted variable.

{
  acknowledged: true,
  insertedCount: 2,
  insertedIds: {
    '0': new ObjectId("63c1bf10d3e0559a1c6d54a3"),
    '1': new ObjectId("63c1bf10d3e0559a1c6d54a4")
  }
}

The insertedCount property shows the number of documents inserted, and the insertedIds documents contain the list of ids inserted.

Do not that insertedIds is an object and not an array. Hence to access the inserted id you have to wrap the index in a string, e.g:

console.log(docsInserted.insertedIds['0'])

And to iterate over the ids you can use for in loop

for (key in docsInserted.insertedIds) { console.log(docsInserted.insertedIds[key]) }
Chat API Trusted by world’s biggest corporations | DeadSimpleChat
Chat API and SDk that supports 10 Million Concurrent Users. Features like Pre-Built turn key Chat Solution, Chat API’s, Customization, Moderation, Q&A, Language Translation.

Find Documents

To find the documents inserted in the MongoDB collection, we can use the findOne and find methods.

The findOne method as the name suggests returns a single document that matches the query. whereas the find method returns an array of documents.

Find Single Document:

To find a single document use the findOne command. In the example below we will find a document by the _id.

The insert command that we ran returned the, "id" of the document.

To look up a document by the "id", query the _id field and if they have the document id in string then we wrap it in the ObjectId method to generate the ObjectId of the string id and pass it to the findOne method.

const { MongoClient, ObjectId } = require("mongodb");

const uri = "mongodb://localhost:27017";

const client = new MongoClient(uri);

(async function () {
  const db = client.db("mydb");
  const doc = await db.collection("books").findOne({
    _id: ObjectId("63c1bf10d3e0559a1c6d54a3"),
  });

  console.log("Document found:", doc);
})();

Running the code above returns the document that we have saved

Find by dates and time range

We can also query documents by date, in our books collection each document has certain dates, like the published_date and the created date under each review.

We can query the time frame using the $gt, $gte, $lt and $lte operators:

  • $gt: This is called the "greater than" operator. If we use this operator, we are trying to find anything greater than the specified value.
  • $lt: This is called the "less than" operator. If we use this operator, we are trying to find anything less than the specified value.
  • $gte: This is called the "greater than or equal to" operator. If we use this operator, we are querying to find anything greater than or equal to the specified value.
  • $lte: This is called the "less than or equal to" operator. If we use this operator, we are trying to find anything less than or equal to the specified value.
The $gt, $gte, $lt, $lte operator can be used to query dates as well as numbers along with other things.

Let's look at the following queries:

Find books that are published on or after 1 January 2000

To find the books published on or after 1 January 2000, we will use the $gte operator and query the field published_date

And our query will look like this:

db.collection("books").find({
      published_date: {
        $gte: new Date("1 Jan, 2000"),
      },
}).toArray();

The findOne method returns a single document whereas the find method returns a cursor.

We will learn about cursors later in this blog post, and how to iterate over them, but we can call the toArray()  method converts the cursor into an array of documents.

Here is the complete code:

const { MongoClient, ObjectId } = require("mongodb");

const uri = "mongodb://localhost:27017";

const client = new MongoClient(uri);

(async function () {
  const db = client.db("mydb");
  const docs = await db
    .collection("books")
    .find({
      published_date: {
        $gte: new Date("1 Jan, 2000"),
      },
    })
    .toArray();

  console.log("Documents: ", docs);
})();

When we run the program we get the following output:

Find books published between January 1, 1945 to Jan  1, 1965

To query a time range we will use both $gte and $lte operators in our query, and our query would look like this:

  const docs = await db
    .collection("books")
    .find({
      published_date: {
        $gte: new Date("Jan 1, 1945"),
        $lte: new Date("Jan 1, 1965"),
      },
    })
    .toArray();

In the published_date field we have specified both $gte and $lte operators to query all the books published between Jan 1, 1945, and Jan 1, 1965.

Here is the full code example:

const { MongoClient, ObjectId } = require("mongodb");

const uri = "mongodb://localhost:27017";

const client = new MongoClient(uri);

(async function () {
  const db = client.db("mydb");
  const docs = await db
    .collection("books")
    .find({
      published_date: {
        $gte: new Date("Jan 1, 1945"),
        $lte: new Date("Jan 1, 1965"),
      },
    })
    .toArray();

  console.log("Documents:", docs);
})();

And we get the following output:

Find items in an array

Our books collection contain documents that contain some arrays, and an array of objects. In MongoDB, we can easily query the arrays and nested documents inside the arrays.

Let's look at some query examples:

Find all documents where the genre is "literary_fiction"

If we look at our book document, it contains a field called as genre which is an array of strings.

To query this we can simply create the query where genere is literary_fiction and it will return to us all the documents that have literary_fiction in the genere array.

await db
    .collection("books")
    .find({
      genre: "literary_fiction",
    })
    .toArray();

It is a very simple query, and MongoDB automatically detect that genre is an array and we are looking for an item inside the array.

Here is the complete code:

const { MongoClient, ObjectId } = require("mongodb");

const uri = "mongodb://localhost:27017";

const client = new MongoClient(uri);

(async function () {
  const db = client.db("mydb");
  const docs = await db
    .collection("books")
    .find({
      genre: "literary_fiction",
    })
    .toArray();

  console.log("Docs:", docs);
})();

And we get the following output:

Find all the documents where the genre is "literary_fiction" or "classic"

To find all the documents where the genre is either "literary_fiction" or "classic" we can use the $in operator.

The $in operator accepts an array of items and finds the documents that match either or both the provided options.

Our query would look like this:

db.collection("books")
    .find({
      genre: {
        $in: ["literary_fiction", "classic"],
      },
    })
    .toArray();

Here is the complete code example:

const { MongoClient, ObjectId } = require("mongodb");

const uri = "mongodb://localhost:27017";

const client = new MongoClient(uri);

(async function () {
  const db = client.db("mydb");
  const docs = await db
    .collection("books")
    .find({
      genre: {
        $in: ["literary_fiction", "classic"],
      },
    })
    .toArray();
  console.log("Docs:", docs);
})();

And the output of our code would be:

Query Documents in an array: Find Books that contain a review by username "stacy"

If we look at our book object, we have a reviews array, which is an array of objects, and it looks like this:

      reviews: [
        {
          rating: 5,
          created: new Date("Jan 8, 2023"),
          title: "Excelled read",
          description:
            "This is a very good read, I couldn’t put it down for a day until I finished the book.",
          username: "lora",
        },
        {
          rating: 3,
          created: new Date("Jan 8, 2020"),
          title: "Huge disappointment.",
          description:
            "After all the rave reviews I was expecting something exceptional but was completely underwhelmed.",
          username: "stacy",
        },
      ],

So if we want to query our books collection with a field inside the reviews array, we can easily do it with MongoDB.

To query the array of objects inside of a document we simply use <array_field>.<object_field>

For our example, we want to find the review by username stacy, we will construct our query field as reviews.username where reviews is the array and username is the field inside the objects in the array.

Our query will look like this:

db
    .collection("books")
    .find({
      "reviews.username": "stacy",
    })
    .toArray();

Here is our complete example:

const { MongoClient, ObjectId } = require("mongodb");

const uri = "mongodb://localhost:27017";

const client = new MongoClient(uri);

(async function () {
  const db = client.db("mydb");
  const docs = await db
    .collection("books")
    .find({
      "reviews.username": "stacy",
    })
    .toArray();

  console.log("Docs", docs);
})();

And our output will be:

And If we print the reviews array using console.log(docs[0].reviews) we can indeed see a review by the username stacy.

Chat API Trusted by world’s biggest corporations | DeadSimpleChat
Chat API and SDk that supports 10 Million Concurrent Users. Features like Pre-Built turn key Chat Solution, Chat API’s, Customization, Moderation, Q&A, Language Translation.

Update Documents and Upsert

To update the document we have two methods, updateOne and updateMany.

The Update method also has an upsert option that allows you to insert a new document if the document is not found.

Update Single Document:

We can update a single document using the findOne method, let's look at an example:

Update the pages of the book to 398 where isb_10 is 0735219109

The query to update pages to 398 where isb_10 is 0735219109 will be very simple

db.collection("books").updateOne(
    {
      isbn_10: "0735219109",
    },
    {
      $set: {
        pages: 398,
      },
    }
  )

Here is the full code example:

const { MongoClient, ObjectId } = require("mongodb");

const uri = "mongodb://localhost:27017";

const client = new MongoClient(uri);

(async function () {
  const db = client.db("mydb");
  const updateInfo = await db.collection("books").updateOne(
    {
      isbn_10: "0735219109",
    },
    {
      $set: {
        pages: 398,
      },
    }
  );

  console.log(updateInfo);
})();

When we run the above code, we get the following output:

In the output, we can see that matchedCount as 1 and modifiedCount as 1. It indicates that it matched one document and updated one document.

If we run this script again, the matchedCount will be 1 and the modifiedCount will be 0.

Array Insert: $push

The field reviews is an array of objects, the update method, we can also update the arrays inside the MongoDB document.

To add the item to an array inside of a MongoDB document we have to use the $push operator.

Let's look at some examples:

Add a review to the book 1984

To a review, we have to push an item in the reviews array.

And our query will look something like this:

db.collection("books").updateOne(
    {
      title: "1984",
    },
    {
      $push: {
        reviews: {
          rating: 4,
          title: "Good Read",
          description: "I enjoyed reading this book",
          username: "stacy",
        },
      },
    }
  );

Instead of $set we have used the $push operator to add a new item to the reviews array.

The complete code for the example looks like this:

const { MongoClient, ObjectId } = require("mongodb");

const uri = "mongodb://localhost:27017";

const client = new MongoClient(uri);

(async function () {
  const db = client.db("mydb");
  const updateInfo = await db.collection("books").updateOne(
    {
      title: "1984",
    },
    {
      $push: {
        reviews: {
          rating: 4,
          title: "Good Read",
          description: "I enjoyed reading this book",
          username: "stacy",
        },
      },
    }
  );
  console.log(updateInfo);

  const doc = await db.collection("books").findOne({
    title: "1984",
  });

  console.dir(doc);
})();

In the above example, we have added a review by stacy and then printed the updated document using findOne.

The output looks like this:

Array Delete: Delete Item inside an array $pull

Let's look at an example to delete the item inside an array. Consider the following document

{
  _id: ObjectId("63c56efb31fd431a23e9077d"),
  title: '1984',
  authors: [ { firstName: 'george', lastName: 'orwell' } ],
  genre: [ 'classic', 'science_fiction' ],
  published_date: ISODate("1949-06-08T04:00:00.000Z"),
  pages: 298,
  isbn_10: '1443434973',
  isb_13: '978-1443434973',
  reviews: [
    {
      rating: 5,
      created: ISODate("2023-01-03T05:00:00.000Z"),
      title: 'Must read',
      description: 'Every citizen with a brain or even an inquisitive mind should read this.',
      username: 'chris'
    },
    {
      rating: 3,
      created: ISODate("2022-11-09T05:00:00.000Z"),
      title: 'Great',
      description: "Great really enjoyed reading this book. It's not a 5 star bc it was dull at times",
      username: 'blaze'
    }
  ]
}

The reviews in an array of objects, if we want to delete a "review", then we have to use the $pull operator.

Let's look at some query examples:

Delete the reviews with a rating less than 5 from the book 1984

 db.collection("books").updateOne(
    {
      title: "1984",
    },
    {
      $pull: {
        reviews: {
          rating: {
            $lt: 5,
          },
        },
      },
    }
  );

Here is the complete code example:

const { MongoClient, ObjectId } = require("mongodb");

const uri = "mongodb://localhost:27017";

const client = new MongoClient(uri);

(async function () {
  const db = client.db("mydb");
  const updatedInfo = await db.collection("books").updateOne(
    {
      title: "1984",
    },
    {
      $pull: {
        reviews: {
          rating: {
            $lt: 5,
          },
        },
      },
    }
  );
  console.log("Updated Info", updatedInfo);

  const document = await db.collection("books").findOne({
    title: "1984",
  });

  console.dir(document);
})();

We get the following output:

Delete all reviews from user chris across all documents

The query will look like this:

db.collection("books").updateMany(
    {},
    {
      $pull: {
        reviews: {
          username: "chris",
        },
      },
    }
  );
  

Here is the complete code example:

const { MongoClient, ObjectId } = require("mongodb");

const uri = "mongodb://localhost:27017";

const client = new MongoClient(uri);

(async function () {
  const db = client.db("mydb");
  const updatedInfo = await db.collection("books").updateMany(
    {},
    {
      $pull: {
        reviews: {
          username: "chris",
        },
      },
    }
  );
  console.log("Updated info:", updatedInfo);
})();

Array Update Operator:

Let's look at an example of updating an array inside of the document.

Update all the reviews by username stacy to stacyandrews

The "reviews" is an array of objects inside of our book document. Using MongoDB we can easily update the objects inside of an array in a document.

To query by a key inside an object we use <array_name>.<object_key> so for our example, it would be reviews.username

To update the key we have to use the $ operator. The $ represents the matched index, so to update the username we have to use reviews.$.username

Let's see what our query would look like:

This is the right way to do it:

db.collection("books").updateMany(
    {
      "reviews.username": "stacy",
    },
    {
      $set: {
        "reviews.$.username": "stacyandrews",
      },
    }
  );

If you do it like this, the query will fail!

db.collection("books").updateMany(
    {
      "reviews.username": "stacy",
    },
    {
      $set: {
        "reviews.username": "stacyandrews",
      },
    }
  );

So don't forget to use the $ operator when updating the item inside an array.

We are using the updateMany method to update all the reviews that have a username stacy to stacyandrews

The complete code example looks like this:

(async function () {
  const db = client.db("mydb");
  const updatedInfo = await db.collection("books").updateMany(
    {
      "reviews.username": "stacy",
    },
    {
      $set: {
        "reviews.$.username": "stacyandrews",
      },
    }
  );

  console.log(updatedInfo);

  // Finding all the documents that have review
  // by stacyandrews
  const documents = await db
    .collection("books")
    .find({
      "reviews.username": "stacyandrews",
    })
    .toArray();

  console.log("Printing reviews from all documents: ");
  for (let doc of documents) {
    console.log(doc.reviews);
  }
})();
Chat API Trusted by world’s biggest corporations | DeadSimpleChat
Chat API and SDk that supports 10 Million Concurrent Users. Features like Pre-Built turn key Chat Solution, Chat API’s, Customization, Moderation, Q&A, Language Translation.

Delete:

To delete a document from a MongoDB collection you can use the deleteOne and deleteMany method.

As the name suggests, the deleteOne method is used to delete a single document and deleteMany is used to delete multiple documents matching the query.

Delete Single Document

Let's look at an example to delete a single document:

Delete the book that has the title "Where the Crawdads Sing"

db.collection("books").deleteOne({
    title: "Where the Crawdads Sing",
});

Here is the complete code:

const { MongoClient, ObjectId } = require("mongodb");

const uri = "mongodb://localhost:27017";

const client = new MongoClient(uri);

(async function () {
  const db = client.db("mydb");
  const deletedInfo = await db.collection("books").deleteOne({
    title: "Where the Crawdads Sing",
  });

  console.log("Deleted Info:", deletedInfo);
})();

And it returns the following output:

The output shows the deletedCount of 1.

Delete Multiple Documents

To delete multiple documents use the deleteMany method.  Let's look at an example.

Delete all the books that contain the genre "classic:

db.collection("books").deleteMany({
        "genre": "classic"
});

Here is the complete code example:

const { MongoClient, ObjectId } = require("mongodb");

const uri = "mongodb://localhost:27017";

const client = new MongoClient(uri);

(async function () {
  const db = client.db("mydb");
  const deletedInfo = await db.collection("books").deleteMany({
    genre: "classic",
  });

  console.log("Deleted Info", deletedInfo);
})();

It returns the following output:

Our query matched and deleted two documents.


Conclusion:

In this Guide, we have learned how to Create, Insert, Update and Delete documents in MongoDB.

In Part 2 of this Guide, we will learn about Cursors, Transactions, Aggereation and Indexes.

Add Chat to your App or Website with Dead Simple Chat

Dead Simple Chat

Dead Simple Chat offers powerful Chat API and SDK to add Live Streaming, Group and 1-1 Chat to your App, Website, Live Stream or Virtual Event.

The Chat can be customised to fit any use case, from Sass application, Social Platform, and Education to Virtual Events.

Signup for Free