CRUD Operations in MongoDB Tutorial

Welcome to the third chapter of the MongoDB turorial (part of the MongoDB Developer and Administrator Course). This chapter will explain how to perform Create, Retrieve, Update and Delete or CRUD operations in MongoDB.

Let us explore the objectives of this chapter in the next section of CRUD Operations.

Interested in learning more about MongoDB? Enroll in our MongoDB course today!

Objectives

After completing this lesson, you will be able to:

  • Explain how to perform data modification in MongoDB.

  • Explain how to perform a batch insert, ordered bulk insert, and unordered bulk insert.

  • Explain how to insert documents into MongoDB collection.

  • Explain how to modify, update, upsert, and delete documents from MongoDB collection.

  • Identify the steps to use different query modifiers such as find, Query Conditionals, Queries, $not, Regular Expressions, and so on.

  • Identify the steps to retrieve documents by using the find query, Or condition, cursor, batch insert.

  • Identify the steps to retrieve documents for array fields.

  • Identify the steps to perform a batch insert, ordered bulk insert, and unordered bulk insert.

We will discuss data modification In the next section of CRUD.

Data Modification in MongoDB

Data modifications are operations that involve creating, updating, or deleting data. These operations in MongoDB help modify the data of a single collection.
Inserts is a basic data modification operation used for adding data to the MongoDB database. You can insert a document in a collection by using this method.  

db.courses.insert({Name:“SimpliLearn",

Address:" 10685 Hazelhurst Dr, Houston, TX 77043, United States”,

Courses: [“Big Data”,”Python”,”Android”,”PMP”,”ITIL”],

Offices: [ “NYK”,”Dubai”,”BLR”]

});

For example, the query shown above is used for inserting a document which has the name, address, courses, and offices fields. The db.collection.save() (pronounce as the D-B dot collection dot save) method will update the document if it already exists or will insert a new document.

In the next section of CRUD Operations, we will discuss what Batch Insert is.

Batch Insert in MongoDB

A Batch Insert is an operation that allows storing of multiple documents in a database at one time. You can send hundreds or thousands of documents in a batch at a time. This makes the whole insert operation faster than normal inserts as multiple documents can be inserted simultaneously.

A batch insert is performed as a single Transmission Control Protocol or TCP request. This means that you do not need to make hundreds of individual requests to perform an insert. Batch insert eliminates the header processing activity for a message and this reduces the insert time.

Each document has a header which tells the database the kind of operation to be performed on a collection. Typically, batch inserts are used in applications for storing server logs and sensors data.

To import raw data from Relational Database Management System or RDBMS databases, such as Oracle or MySQL (pronounce as My sequel), instead of batch insert, use the command-line tools, such as mongoimport (pronounce as mongo import). At times you may need to transform the data like adding a custom _id (pronounce as underscore ID) field before saving it to MongoDB.

Remember, MongoDB does not accept messages which are heavier than 16 MB. Therefore, batch insert has a limit to how many messages it can include.

In the next section of CRUD Operations, we will discuss Ordered Bulk Insert.

Ordered Bulk Insert

With an ordered operations list, MongoDB performs the write operations in the list serially. If any error occurs during one of the write operations, MongoDB returns without executing the remaining write operations in the list.

MongoDB groups an ordered operation by its type and continuity. It groups contiguous operations of the same type together.

For example, an ordered list contains two insert operations followed by an update operation followed by another insert operation. MongoDB separates the operations into three groups. Group one will have the two insert operations, group two will have the update operation, and group three will have the last insert operation.

This behavior of MongoDB is subject to change in future versions. In addition, each group can have a maximum of 1000 operations. If the number of operations is more than 1000, MongoDB divides the group into smaller groups each having 1000 or less operations.

For example, if a bulk operations list contains 5000 insert operations, MongoDB creates 5 groups, each having 1000 operations. If you want to see how operations are grouped together and executed, enter the Bulk.getOperations (pronounce as bulk dot get operations) command after executing the bulk insert command. The example given above is an ordered bulk insert where three documents will be inserted at one time. 

In the next section of CRUD Operations, we will view a demo on how to perform an ordered bulk insert.

Unordered Bulk Insert

In an unordered operations list, MongoDB can perform write operations in parallel in a random order. If an error occurs during a write operation, MongoDB will perform remaining write operations uninterrupted. When performing an unordered list of operations, MongoDB groups them.  

For executing an unordered bulk operation, MongoDB may reorder the operations in the list for performance enhancement. Therefore, the applications must not depend on the sequence of operations when performing unordered bulk operations.

You can call Bulk.getOperations() (read as bulk dot get operations ) to see how these operations are grouped together and executed by the MongoDB.

The unordered bulk command given above will insert three documents in one go without concerning about order of insertion. In the next section of CRUD Operations, we will view a demo on how to perform an unordered bulk insert operation.

Inserts: Internals and Implications

When an insert operation is executed, the language driver converts the data structure into Binary JSON or BSON, before sending to the database. The database looks for a "_id" (pronounce as underscore ID) key and confirms that the document has not exceeded 16MB.

However, other than that, it does not perform any data validation and saves the document to the database as is. MongoDB supports different language drivers, which check for invalid data such as whether the strings are UTF-8 compliant and filter out unrecognized data types before sending them to the database.
If you are unsure about the driver you are using, start the database server with the –objcheck option. This will examine the structural validity of each document before inserting them into the database). MongoDB does not perform any code execution on inserts. Hence, is not vulnerable to traditional injection attacks.

In the next section of CRUD Operations, we will discuss how to retrieve documents.

Want to test your MongoDB skills? Take our MongoDB Free Practice Test Today

Retrieving the documents

Typically, a MongoDB query targets specific documents in a collection. These queries define the criteria or condition based on which MongoDB identifies the documents that need to be returned to the clients.

A query may include a projection that defines the fields that match the document fields to return. You can choose to modify queries to impose limits, skips, and sort orders.

db.items.find( {available: true },{item:1,} ).limit(5)

In the query given above, items is the collection, {available: true} (pronounce as available true) is the query criteria,},{item:1,} ) (Pronounce as item 1) is its projection, and limit(5) (pronounce as limit 5) is the modifier.

In the next section of CRUD Operations, we will discuss how to specify equality condition.

Specify Equality Condition

The findOne() (Pronounce as find one) method is used to find the first record in the document. If you want the results displayed properly formatted, also use the pretty method.

For example, the query- db.items.find().pretty() (pronounce as d-b dot items dot find dot pretty method) helps select all documents in a collection and are displayed in a proper format.
An empty query document selects all documents in the collection.

For example, the db.items.find( {} ) (pronounce as d-b dot items dot find with empty query clause) query will find all documents in a collection. If you do not specify a query document to the find() method, it is similar to triggering an empty query document.

Therefore, the operation db.items.find()(pronounce as d-b dot items dot find) is equivalent to the operation db.items.find( {} ) (pronounce as d-b dot items dot find with empty query clause)

db.items.find( {} ) = db.items.find()

To specify an equality condition, use the query document { <field> : <value> } (pronounce as field value). This selects all documents that contain the with the specified . Below is the example of Equality condition used in MongoDB query.

db.items.find( {available: true } )

The query db.items.find( {available: true } ) (pronounce as d-b dot items dot find available true) retrieves all documents from where the available field has the value true.

In the next section of CRUD Operations, we will specify conditions using query operators.

$in, $or, and “AND” Conditions

You can also specify conditions using query operators.

  • $in: Queries a variety of values for a single key. If you have more than one possible value to match a single key, use an array of criteria with "$in". The first query example given below is used to select all documents in the items collection where the value of the type field is either ’true’ or ‘false’.

db.items.find( {available : { $in: [true, false ] } } )

  • $or: Queries similar values as $in the operator. However, it is recommended to use the $in operator when performing equality checks on the same field.

  • AND: A compound query can specify conditions for more than one field in the collection’s documents.  The logical conjunction AND is used to connect the various clauses of a compound query. This helps the query to select the documents that match all the specified conditions.

db.items.find( {available: true, soldQty: { $lt: 900 } } ).

In the second query parameter given above, two conditions are specified. One for an equality match on the field available and another for less than comparison match on the field soldQty. This query selects all documents where the available field value is ‘true’ and the value in the price field is less than 900.
In the next section of CRUD Operations, we will discuss the $or operator.

$or Operator

Following are the functions of the $or operator:

  • Returns the value true when any of its expressions evaluate to true or accepts any argument expressions.

  • Defines a compound query where each clause are joined with a logical OR conjunction. This compound query selects all documents in the collection that match minimum one condition.

db.items.find({ $or: [ {soldQty : { $gt: 500 } }, { available:true } ] })

In the example given above, the query document selects all documents in the collection where the field soldQty (pronounce as Sold quantity) has a value greater than 500 or the value of the available field is true.

In the next section of CRUD Operations, we will discuss AND as well as Or conditions.

Specify AND/OR Conditions

If you include additional clauses, you can specify the exact conditions for matching a document. The query example given below selects all documents in the collection where:

  • The value of the available field is true

  • The soldQty has a value greater than 200

  • The value of the item field is “Book”

db.items.find({ available:true,$or: [ {soldQty : { $gt: 200 } }, {item: “Book” } ]})

The “$not” is a meta conditional operator. You can apply a $not to any other criteria. In the example given below, the “$mod” queries the keys whose values, when divided by the first given value, shows a remainder of the second value.

db.items.find({“_id" : {"$not" : {"$mod" : [4, 1]}}})

The query given above will give you all those documents whose id when divided by 4 will not have any remainder.

In the next section of CRUD Operations, we will discuss regular expressions.

Regular Expression

Regular expressions are used in string matching of flexible items. For example, you want to find all items whose value starts with “Pe” (pronounce as P-E), such as pen and pencil. You can use a regular expression to do case-insensitive matching.  

db.items.find({item:/pe/i})

 For example, use the first expression given above to search for all instances of pen or pencil.

 In addition, if you want to match any variation of the item, Pen, you can continue to improve the regular expression. 

db.items.find({item: /Pen?/i})

To search for any variation, use the second expression given above. 

In the next section of CRUD Operations, we will discuss Array exact match.

Array Exact Match

You can use equality matches to match a single element in the array field. If the array contains minimum one element with the specified value, these specifications match.

In the example db.items.find( {country_codes: 5 } ), the operation queries for documents that contains an array country_codes that contains 5 as one of its elements.

You can also use an equality match to match a specific element of an array. 

db.items.find( { 'country_codes.0': 1 } ) 

For this, use the dot notation shown on the second query given above.
In the next section of CRUD Operations, we will discuss array projection operators.

Array Projection Operators

MongoDB provides the following projection operators for fields containing arrays

  1. $elemMatch,

  2. $slice, and

  3. $. (pronounce as ElemMatch, Slice and Position operators)

db.items.find( { _id: 5 }, {country_codes : { $slice: 2 } } )

 The first operation shown above uses the $slice projection operator to retrieve only the first two elements in the country_codes array. $elemMatch, $Slice, and the Positional operator can be used to return a subset of elements for an array key.

db.items.find( {country_codes : { $elemMatch: { $gte: 3, $lte: 6 } } } )

The second operation shown above uses $elemMatch to get that document in which the country_codes array field contains a value greater than equal and less than equal to 6. 

In the next section of CRUD Operations, we will discuss $where query.

$Where Query

Key/value pairs express a query very well. However, they cannot represent all queries. The "$where" clauses, which allow arbitrary execution of JavaScript as part of your query can represent the queries that key/value pairs fail to represent. 

The $Where clauses allow you to perform any logical execution within a query.

For example, it allows you to return documents from the collection that have two different keys with the same value.  

The most common scenario is comparing the values for two keys in a document.

> db.foo.insert({"apple" : 8, "spinach" : 4, "watermelon" : 4})
   db.foo.find({"$where" : function () {
... for (var current in this) {
... for (var other in this) {
… if (current != other && this[current] == this[other]) {
... return true;
}} }
.. return false;
... }});
db.foo.find({"$where" : "this.x + this.y == 10"})
> db.foo.find({"$where" : "function() { return this.x + this.y == 10; }"})​
 

For example, the query shown above has a list of items and will return documents where any two of the values are equal. If the function returns true, the document will be part of the result set. If it returns false, it will not be a part of the results set.

You can also use strings to specify a "$where" query. The two "$where" queries shown above are equivalent.  

In the next section of CRUD Operations, we will discuss cursor.

Cursor

The database uses a cursor to return results from the find. Typically, the client-side implementations of cursors allow you to control a query output.

For example, you can limit the number of results, skip some results, sort results using keys, and perform other powerful operations. To create a cursor with the shell, add documents into a collection, perform a query on the documents, and then allocate the results to a local variable, such as "var".  

This allows you to look at one result at a time. Even if you store the results in a global variable or no variable, the MongoDB shell can iterate through and display the first few documents. To iterate through the results, use the next method on the cursor. If you want to check if there is another result, use hasNext.

var cursor = db.collection.find();

while (cursor.hasNext()) {

... obj = cursor.next();

... // do stuff

... }

> var cursor = db.people.find();

> cursor.forEach(function(x) {

... print(x.name);

... });

db.c.find().skip(3)

db.c.find().sort({username : 1, age : -1})

The example given above shows what a typical loop through result looks like. 

The cursor.hasNext() method calls to check for the next result, and the cursor.next() fetches it. At this point, the query is sent to the server. The shell fetches the first 100 results or the first 4MB of results, whichever is smaller immediately so that the next or hasNext clauses do not have to make trips to the server. 

After the client has run through the first set of results, the shell contacts the database and requests for more results. This process continues till the cursor is exhausted and all results are returned. 

We will continue with the cursor in the next section of CRUD Operations.

Cursor (contd.)

The most common queries have the options to limit the number of results returned, skip a number of results, and sort them. You must include these options before sending a query to the database. 

To set a limit to the number of results fetched, add the limit function to your call to find. 

For example, if you want the query to return only three results from the items collection, use the query statement db.items.find().limit(3). Typically, limit sets an upper limit, not a lower limit. If the number of documents matching your query are less than the number specified in the limit function, then only those documents will be returned. 

The skip function is similar to limit. The query db.c.find().skip(3) (pronounce d-b dot c dot find dot skip three) will skip the first three matching documents and return other matches. It will not return any documents if your collection contains less than three documents. 

The Sort function takes two parameters, the first parameter is the field name on which sorting should be performed and the second parameter is a key/value pairs where keys are key names and the values are the sort directions.

There can be two sort direction, 1 or ascending or -1 or descending. 

db.c.find().sort({username : 1, age : -1}) 

For instance, to sort the results by "username" in the ascending order and "age" in the descending order, use the query given above. 

In the next section of CRUD Operations, we will discuss pagination.

Pagination

MongoDB is a document based data store and hence pagination is one of the most common use cases of it. Pagination is a type of user control that lets the user browse a large number of database rows in the form of pages. You paginate whenever you want to process result in chunks. 

You can combine the limit, skip and sort methods for pagination.
For example, suppose a buyer searches for mobile on your online store.

To display 25 results sorted by price from high to low per page, perform the query given below.

db.stock.find({"desc" : “mobile"}).limit(25).sort({"price" : - 1}) 

To display the Next Page for more results, use the second query given below.

db.stock.find({"desc" : “mobile"}).limit(25).skip(25).sort({"price" : - 1}) 

This will skip the first 25 matches, which they saw on page 1. However, including large skips may slow down the display, hence must be avoided. 

In the next section of CRUD Operations, we will continue our discussion on pagination.

Pagination: Avoiding Larger Skips

Using pagination, you can control the number of documents being returned by the find() query. You can use the limit and skip functions to achieve pagination. In addition, you may perform pagination without using skips depending on your query.

var page1 = db.foo.find().sort({"date" : -1}).limit(100)

For example, to display the first page of a query result in the descending chronological order, use the first query given above. Next, you can set the "date" value of the last page as the criteria for getting the next page.

var latest = null;

// display first page

while (page1.hasNext()) {

latest = page1.next();

display(latest);

}

// get next page

var page2 = db.foo.find({"date" : {"$gt" : latest.date}});

page2.sort({"date" : -1}).limit(100);

The second example given above presents a pagination query without using a skip.  

In the next section of CRUD Operations, we will discuss advance query option.

Advance query option

There are two types of queries executed by MongoDB.

  1. Plain

  2. Wrapped

MongoDB wraps query into a larger document by specifying many query options before sending them to the server. Typically, language drivers help to add arbitrary options to queries.

Apart from this, the following options help in adding to queries.

  • $maxscan: Integer This specifies the maximum number of documents that are scanned for a query.

  • $min: Document This starts the criteria for querying.

  • $max: Document This ends the criteria for querying.

  • $hint: Document This tells the server which index to use for the query.

  • $explain: Boolean This explains how the query will be executed, such as the indexes used, number of results to be displayed, the duration, and so on. It does not perform the actual query.

  • $snapshot: Boolean This forces the query to use the index of the _ID field.

In the next section of CRUD Operations, we will discuss update.

Update Operation

In MongoDB, the db.collection.update() method is used to modify existing documents in a collection. This method defines the query criteria to identify the documents that need an update and all document options that affect its behavior. 

Operations performed by an update are atomic within a single document. For example, the update() method is used by MongoDB to update the documents in a collection.

This method has the following as its parameter:

  • An update condition

  • An update operation

  • An options document

You need to use a structure and syntax for specifying the update condition as you do for query conditions. You need to use “multi:true” (pronounce as multi true) to update multiple documents. 

In the next section of CRUD Operations, we will discuss $SET in MongoDB.

$SET

The "$set" modifier specifies the value of a key. If a key does not exist, $set creates it. This modifier updates schema or adds user-defined keys.
You need to perform the following steps to use a $set modifier.

Step 1: Use update operators to change field values.  

You can use a $set operator to update the category and the details fields for the document which has item field value as “Book”.” For documents with items equal to "Book", use the $set operator to update the category and the details field as per the specified values. 

db.items.update({ item:"Book"},{$set: {category: 'NoSQL',details: {ISDN: "1234",publisher:"XYZ"}}}); 

The first example given above presents the update operator command. 

Step 2: Update an embedded field. You can use the dot notation to update a field within an embedded document. When using this, add the dotted field name in quotes. 

db.items.update({ item: “Pen" },{ $set: { "details.model": "14Q2" } }) 

The second command updates the model field within the embedded details document. 

Step 3: Update multiple documents. 

db.items.update({ item: “Pen" },{$set: { category: "stationary" },$currentDate: { lastModified: true }},{ multi: true }) 

To update the category field to "stationary" and the lastModified field to the current date for all documents that have item field equal to "Pen", use the third command given above. This will update multiple documents.

In the next section, we will discuss modifiers in MongoDB.
 

Want to know more about MongoDB? Enroll in our MongoDB course today!

$Unset and $inc Modifiers

$inc (pronounce as ink) operator can be used for incrementing and decrementing numbers such as long, integer, or double.

db.items.update({“item" : “Pencil"}, {"$inc" : {“soldQty" : 1}}) 

The first query given above is incrementing the value of the soldQty field by one for the document representing "Pencil" Note that you cannot apply $inc modifier to non-numbers.

The value of the "$inc" key must be a number because you cannot increment a non-numeric value. To remove existing fields from the document, you can use $unset (pronounce as unset) modifier.

> db.items.update( {soldQty: { $gt: 700} },{ $unset: {soldQty: “1000" } },{ multi: true })

To remove the soldQty field for all the documents whose soldQty field value is greater than 700, use the second query given above.

In the next section of CRUD operations, we will discuss $Push and $addToSet.

$Push and $addToSet

To add a new element to an array field, you can use the $push (pronounce as push) function. The $push function adds the element at the end of an array if the array already exists otherwise it will create an array field and insert the element into that field.

To add another ingredient, you can use the "$push" function again.

db.user.update({“item" : “Pencil”}, {$push : {“ingredients" : {“wood":"California cedar",“graphite":“mixture of natural graphite and chemicals"}}})

The query given above is an example of how to use the $push function to an ingredients key. When adding another email address, you can use the "$addToSet" (pronounce as add to set) modifier to prevent duplicate. 

In the next section of CRUD Operations, we will discuss positional array modifications.

Positional Array Modification

Array modification is not easy when you want to modify some values when there are multiple values in an array.

You can modify the array values in two ways.

  • By position

  • By using the position operator, the "$" (pronounce as a dollar).

For example, you are storing blog post with comments in MongoDB.

db.blog.update({"post" : post_id},{"$inc" : {"comments.0.votes" : 1}})

To increment the votes for the first comment, you can use the first command given above.

 

In many cases, it may not be clear which indexes of the array needs modification without first retrieving the document and examining it. To resolve this, MongoDB offers a positional operator, "$", that helps identify the arrays matching the query document and updates them.

db.blog.update({"comments.author" : "John"}, {"$set" : {"comments.$.author" : "Jim"}}))

For example, if you have a user called John who updates his name to Jim, you can replace it in the comments by using the positional operator shown above.

Note that the positional operator will update only the first match. Therefore, if John makes more than one comment in the blog, the name gets updated only in the first comment.

In the next section of CRUD Operations, we will discuss Upsert.

Upsert

An upsert is a special kind of update. If documents matching update criteria are found, then they are updated. Otherwise, it will insert new documents into the collection. To use upsert, you need to pass “upsert: true” as a parameter.

db.items.update({“item" : “Bag"}, {"$inc" : {“soldQty" : 1}}, {upsert:true})

The first command shown above is an example of the upsert operation. By default, update operations modify only the first found document that matches the query criteria. If there are many matching documents, then they remain unchanged.

To update all the documents that match the query criteria, you can use true as the fourth parameter to update all of the documents. Multi updates are the efficient operation of adding a new feature to all the documents. Suppose, for example, you want to present a gift to every user on their birthday.

db.users.update({item: "10/22/1978"},{$set : {gift : "Happy Birthday!"}}, false, true)

You can use the multi-update command given above to add a "gift" to their account. This would add the "gift" key to all user documents with birthdays on October 22, 1978.

In the next section of CRUD Operations, we will discuss removing documents in MongoDB.

Removing Documents

You can remove data from a collection, using the remove() method.

db.courses.remove()

The first command given above is used for this purpose. However, this will only remove all of the documents in the courses collection, not the collection and indexes created.

Optionally, the remove command treats a query document as its parameter. When this command is used, only those documents that match the query document criteria are removed.

db.items.remove({“item" : “Bag”)

To remove documents from the items collection where the value for "item" is ”Bag”, use the second command given above.

db.items.remove({" item" : “Bag},1)

To remove a single document, call the remove() method with the two parameters. The third command given above is used to remove one document from the accounts collection where the dormant field equals true.

db.courses.drop()

To delete all documents from a collection, you can use the drop() method. This will remove the entire collection, including the indexes.

Summary

Here is a quick recap of what was covered in this lesson:

  • Data modifications in MongoDB involve creating, updating, or deleting data.

  • Using batch insert, you can send hundreds or thousands of documents in a batch at a time.

  • MongoDB divides an ordered operation into groups containing a maximum of 1000 operations.

  • Unordered bulk inserts allow write operations in parallel in a random order.

  • MongoDB allows you to specify conditions using query operators, such as $in, And, $or.

  • Cursors in MongoDB allows you to modify queries to impose limits, skips, and sort orders.

  • You can use pagination to customize the display results for a search query.

Conclusion

This concludes the chapter CRUD operations in MongoDB. In the next chapter, we will discuss Indexing and Aggregation in MongoDB.

Find our MongoDB Developer and Administrator Online Classroom training classes in top cities:


Name Date Place
MongoDB Developer and Administrator 17 Nov -9 Dec 2018, Weekend batch Your City View Details
  • Disclaimer
  • PMP, PMI, PMBOK, CAPM, PgMP, PfMP, ACP, PBA, RMP, SP, and OPM3 are registered marks of the Project Management Institute, Inc.

Request more information

For individuals
For business
Name*
Email*
Phone Number*
Your Message (Optional)
We are looking into your query.
Our consultants will get in touch with you soon.

A Simplilearn representative will get back to you in one business day.

First Name*
Last Name*
Email*
Phone Number*
Company*
Job Title*