In this post, we will learn how to perform MongoDB CRUD Operations. CRUD stands for Create, Read, Update and Delete. As you can see, these operations are absolutely important for building any useful application.

We need to have a database and collection in order to perform these operations. Therefore, you can refer to the post about MongoDB Database Creation for reference.

1 – MongoDB Create or Insert Data

The first of the MongoDB CRUD Operations we will look at is creating or inserting data into a MongoDB collection.

MongoDB provides a couple of methods i.e. insertOne() and insertMany() to perform these operations. We will look at them one by one.

1.1 – The insertOne() Function

We use the insertOne() function to insert one document into a particular collection.

See below example:

> db.books.insertOne({"bookName":"The Way of Kings", "authorName": "Brandon Sanderson", "genre": "SFF"})
{
	"acknowledged" : true,
	"insertedId" : ObjectId("61cbcd2407216367e66c76f6")
}

Here, books is the collection name. Within the parantheses, we supply a JSON. Basically, this is the document we wish to insert into the collection.

If things are successful, we get the acknowledgment message along with an insertedId. This id is the unique id that MongoDB assigns to every document.

1.2 – The insertMany() Function

The second option at our disposal is the insertMany() function. As the name suggests, we can use it if we want to insert multiple documents to our collection at once.

See below example:

> db.books.insertMany([{"bookName": "Foundation", "authorName": "Isaac Asimov", "genre": "SF"}, {"bookName": "Foundation and Earth", "authorName": "Isaac Asimov", "genre": "SF"}])
{
	"acknowledged" : true,
	"insertedIds" : [
		ObjectId("61cbcffb07216367e66c76f7"),
		ObjectId("61cbcffb07216367e66c76f8")
	]
}

Basically, here we insert two books in our collection. To do so, we provide a JSON array as input to the insertMany() function. Also, we receive two ObjectIds because two new records were inserted.

Here, we can also insert documents with our own id. However, unless we have a very special need, we should simply use the MongoDB generated id. If you see the ObjectIds closely, they are in some sort of sequence. This basically helps in the ordering of documents within the collection.

2 – MongoDB Read or Find Data

The second important operation is to actually read or find data from a MongoDB collection. It is one of the most popular MongoDB CRUD Operations. Again, MongoDB provides multiple options to do so.

2.1 – The find() Function

The easiest way to find records is to use the find() function. See below example:

> db.books.find()
{ "_id" : ObjectId("61cbcd2407216367e66c76f6"), "bookName" : "The Way of Kings", "authorName" : "Brandon Sanderson", "genre" : "SFF" }
{ "_id" : ObjectId("61cbcffb07216367e66c76f7"), "bookName" : "Foundation", "authorName" : "Isaac Asimov", "genre" : "SF" }
{ "_id" : ObjectId("61cbcffb07216367e66c76f8"), "bookName" : "Foundation and Earth", "authorName" : "Isaac Asimov", "genre" : "SF" }

We can also make the output pretty by chaining the pretty() function.

> db.books.find().pretty()
{
	"_id" : ObjectId("61cbcd2407216367e66c76f6"),
	"bookName" : "The Way of Kings",
	"authorName" : "Brandon Sanderson",
	"genre" : "SFF"
}
{
	"_id" : ObjectId("61cbcffb07216367e66c76f7"),
	"bookName" : "Foundation",
	"authorName" : "Isaac Asimov",
	"genre" : "SF"
}
{
	"_id" : ObjectId("61cbcffb07216367e66c76f8"),
	"bookName" : "Foundation and Earth",
	"authorName" : "Isaac Asimov",
	"genre" : "SF"
}

As you can see, the output is formatted in a much more presentable manner.

Important point to note here is that the find() function essentially returns a cursor to the list of documents. This is because there can potentially be millions of documents in a collection. Returning all of them at once will lead to memory issues. Therefore, Mongo shell has a limit of 20 documents along with an option to fetch the next set in case there are more documents in the collection.

We can also find records based on some filtering logic. After all, filtering is a key aspect of any database. For example, we want to find all books written by ‘Isaac Asimov’. See below example on how to do that.

> db.books.find({"authorName": "Isaac Asimov"}).pretty()
{
	"_id" : ObjectId("61cbcffb07216367e66c76f7"),
	"bookName" : "Foundation",
	"authorName" : "Isaac Asimov",
	"genre" : "SF"
}
{
	"_id" : ObjectId("61cbcffb07216367e66c76f8"),
	"bookName" : "Foundation and Earth",
	"authorName" : "Isaac Asimov",
	"genre" : "SF"
}

Here, we provide a filter condition along with the function. A filter condition is basically a JSON object. It will simply fetch all documents that have authorName equal to ‘Isaac Asimov’.

2.2 – The findOne() Function

We also have option to fetch one document using the findOne() function.

Directly executing this function will only return one document as below.

> db.books.findOne()
{
	"_id" : ObjectId("61cbcd2407216367e66c76f6"),
	"bookName" : "The Way of Kings",
	"authorName" : "Brandon Sanderson",
	"genre" : "SFF"
}

Basically, this is the first document in the collection.

We can also pass a filter condition in the findOne() function as below.

> db.books.findOne({"genre":"SF"})
{
	"_id" : ObjectId("61cbcffb07216367e66c76f7"),
	"bookName" : "Foundation",
	"authorName" : "Isaac Asimov",
	"genre" : "SF"
}

Despite the number of documents fulfilling the criteria, findOne() will always return only one document. Basically, the first document that satisfies the filter criteria.

Another thing to notice is that we cannot use the pretty() function with findOne(). We get the below error.

> db.books.findOne({"genre":"SF"}).pretty()
uncaught exception: TypeError: db.books.findOne(...).pretty is not a function :
@(shell):1:1

The pretty() function is basically associated to the cursor that find() returns. However, the findOne() always returns a single document in formatted manner.

3 – MongoDB Update Data

MongoDB provides multiple ways of updating the data. Let’s check them out one by one.

3.1 – The updateOne() Function

The simplest one is to update a single document using the updateOne() function. See below example:

> db.books.updateOne({"_id": ObjectId("61cbcd2407216367e66c76f6")}, {$set: {"price": 10.99}})
{ "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 }

The first argument to the updateOne() function is the filter condition. Here, we use the ObjectId that we want to update. The second argument is what we actually want to update. We use the reserved MongoDB keyword $set to provide another JSON object that contains the price of the book.

After update, the document will appear as below:

{
	"_id" : ObjectId("61cbcd2407216367e66c76f6"),
	"bookName" : "The Way of Kings",
	"authorName" : "Brandon Sanderson",
	"genre" : "SFF",
	"price" : 10.99
}

As you can see, price has been added. The other attributes remain unchanged.

If we don’t use the $set keyword and try to update a document, we get the below error:

> db.books.updateOne({"_id": ObjectId("61cbcd2407216367e66c76f6")}, {"price": 10.99})
uncaught exception: Error: the update operation document must contain atomic operators :
DBCollection.prototype.updateOne@src/mongo/shell/crud_api.js:565:19
@(shell):1:1

Basically, in this situation, MongoDB is not able to determine how it should update the document.

3.2 – The updateMany() Function

We can also update more than one document using the updateMany() function. It follows a similar convention as updateOne(). In other words, the first argument is a filter and the second argument specifies what is to be updated.

See below example:

> db.books.updateMany({"genre": "SF"}, {$set: {"price": 12}})
{ "acknowledged" : true, "matchedCount" : 2, "modifiedCount" : 2 }

Here, we are trying to update the price for books belonging to the “SF” genre. When we execute the command, we get a positive acknowledgement along with the modifiedCount.

The find() function will show the below results:

> db.books.find().pretty()
{
	"_id" : ObjectId("61cbcd2407216367e66c76f6"),
	"bookName" : "The Way of Kings",
	"authorName" : "Brandon Sanderson",
	"genre" : "SFF",
	"price" : 10.99
}
{
	"_id" : ObjectId("61cbcffb07216367e66c76f7"),
	"bookName" : "Foundation",
	"authorName" : "Isaac Asimov",
	"genre" : "SF",
	"price" : 12
}
{
	"_id" : ObjectId("61cbcffb07216367e66c76f8"),
	"bookName" : "Foundation and Earth",
	"authorName" : "Isaac Asimov",
	"genre" : "SF",
	"price" : 12
}

Here, the price got updated for the second and the third books because they belonged to the “SF” genre.

We can also run updateMany() and updateOne() on the basis of numeric fields. See below:

> db.books.updateMany({"price": {$gt: 11}}, {$set: {"inStock": false}})
{ "acknowledged" : true, "matchedCount" : 2, "modifiedCount" : 2 }

We use another special keyword $gt (or greater than). Basically, we check that if price is greater than 11, update the documents with inStock to the value false.

This will again update the second and third records as below:

> db.books.find().pretty()
{
	"_id" : ObjectId("61cbcd2407216367e66c76f6"),
	"bookName" : "The Way of Kings",
	"authorName" : "Brandon Sanderson",
	"genre" : "SFF",
	"price" : 10.99
}
{
	"_id" : ObjectId("61cbcffb07216367e66c76f7"),
	"bookName" : "Foundation",
	"authorName" : "Isaac Asimov",
	"genre" : "SF",
	"price" : 12,
	"inStock" : false
}
{
	"_id" : ObjectId("61cbcffb07216367e66c76f8"),
	"bookName" : "Foundation and Earth",
	"authorName" : "Isaac Asimov",
	"genre" : "SF",
	"price" : 12,
	"inStock" : false
}

3.3 – The update() And replaceOne() Functions

There are two additional functions that need to be examined.

We also have the update() function that works exactly like the updateMany() function if the same arguments are passed as input. See below:

> db.books.update({"genre": "SF"}, {$set: {"price": 12}})

In the above, the output will be the same i.e. all books in “SF” genre will get updated with price set to 12. However, we can also use the update() function without $set. See below:

> db.books.update({"bookName": "Foundation"}, {"inStock": true})

This will update the records as below:

> db.books.find().pretty()
{
	"_id" : ObjectId("61cbcd2407216367e66c76f6"),
	"bookName" : "The Way of Kings",
	"authorName" : "Brandon Sanderson",
	"genre" : "SFF",
	"price" : 10.99
}
{ "_id" : ObjectId("61cbcffb07216367e66c76f7"), "inStock" : true }
{
	"_id" : ObjectId("61cbcffb07216367e66c76f8"),
	"bookName" : "Foundation and Earth",
	"authorName" : "Isaac Asimov",
	"genre" : "SF",
	"price" : 12,
	"inStock" : false
}

The second record is updated with inStock true. However, all other attributes are removed. Basically, the update() function replaces the original document with the new document.

This is the default behaviour of this function. Also, you might want the exact same thing to happen. However, for such a requirement, it is better to use replaceOne() function. It sounds more explicit that we are indeed trying to replace an existing document. The replaceOne() function also uses the same syntax as the update() function.

4 – MongoDB Delete Data

The last of the CRUD operations is deleting data. Again, there are multiple options such as deleteOne() and deleteMany().

4.1 – The deleteOne() Function

Using deleteOne(), we can delete one document. It also accepts a filter argument to provide a condition. If we don’t provide any filter, it will delete the first document in the collection.

See below example

> db.books.deleteOne({"_id" : ObjectId("61cbcd2407216367e66c76f6")})
{ "acknowledged" : true, "deletedCount" : 1 }

Basically, the document with the given ObjectId is deleted.

4.2 – The deleteMany() Function

Next, we have the deleteMany() function. Basically, this function helps delete more than one records. It also accepts a filter argument.

> db.books.deleteOne({"bookName" : "Foundation"})
{ "acknowledged" : true, "deletedCount" : 1 }

We can also use it to delete all the documents. To do so, we simply pass it blank curly braces.

See below example

> db.books.deleteMany({})

This will delete all documents present in the collection.

Conclusion

We have successfully looked at MongoDB CRUD operations. Also, we understood their usage and the various aspects related to them.

In the next post, we will look at MongoDB Projections. You can also check official MongoDB documentation here.

If you have any comments or queries about this post, please mention in the comments section below.


Saurabh Dashora

Saurabh is a Software Architect with over 12 years of experience. He has worked on large-scale distributed systems across various domains and organizations. He is also a passionate Technical Writer and loves sharing knowledge in the community.

0 Comments

Leave a Reply

Your email address will not be published. Required fields are marked *