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
- Connecting To Mongodb
- Background
- Create Documents
- Find Documents
- Update Documents
- Delete
- Conclusion
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/
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 ObjectIDtitle
: title of the bookauthors
: array of authors, some books have multiple authors hence authors is an arraygenre
: array of genre the book belongs topages
: count of the number of pages in the bookreviews
: 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]) }
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.
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);
}
})();
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.
- Rest API with PostgreSQL and Node Js, Step-by-Step Tutorial
- File Upload using Nodejs, Express Multer
- Sending emails in NodeJs with NodeMailer: The Comprehensive Guide
- Environment Variables in NodeJs: The complete Guide
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 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.