MongoDB (Part 2)
On Part 1 we learn the basics of mongodb. In this article, we will have a look at deeper MongoDB operations and build upon our first-article-content we created. This is the second article of the series on MongoDB database tutorial, so, do check out the first part.
Here, we will study about modifying schema of individual documents, embedded documents, Upserts & Inserts and deleting data from collections.
Adding fields to our Book document
Now that we have a better grasp on documents, let’s build our book document with all the necessary details, by adding more fields to it.
We will add two fields, price and score, so that our new document looks like:
{
"name" : "Harry Potter",
"vendor": "BlackSim",
"price": 10.99,
"score": 59
}
Now, we will also add a brand new type, a Date. Dates can be added using the JavaScript Date object and get saved in the database as an ISODate object. So,
{
"name": "Harry Potter",
"vendor": "BlackSim",
"price": 10.99,
"score": 59,
"tryDate": new Date(2012, 8, 13)
}
becomes an ISO date as:
"tryDate": ISODate("2012-09-13T04:00:00Z")
>>> Dates get converted to an ISO format when saved to the database.
Adding a List of topics
Arrays are a great option for storing lists of data. Let’s modify our document so that it includes an array of topics in each book:
{
"name": "Harry Potter",
"vendor": "BlackSim",
"price": 10.99,
"score": 59,
"tryDate": new Date(2012, 8, 13),
"ingredients": ["chamber", 21, "phoenix"]
}
>>> Clearly, We can store any data type within an array.
Adding a Book rating
Each book has 2 different ratings, which are scores based on a scale of 1 to 5. It will look like:
{
"strength": 2,
"easiness": 5
}
Above object needs to go inside the book document. We can do this using Embedded documents.
Embedded Documents
We embed documents simply by adding the documents as a value for a given field.
{
"name": "Harry Potter",
"vendor": "BlackSim",
"price": 10.99,
"score": 59,
"tryDate": new Date(2012, 8, 13),
"ingredients": ["chamber", 21, "phoenix"],
"ratings": {"strength": 2, "easiness": 5}
}
>>> An embedded document doesn’t require an id since it’s a child of the main document.
Insertion with Embedded documents
We’ve cleared out the inventory collection — now let’s add our newly constructed book with a newer structure!
> db.books.insert(
{
"name": "Harry Potter",
"vendor": "BlackSim",
"price": 10.99,
"score": 59,
"tryDate": new Date(2012, 8, 13),
"ingredients": ["chamber", 21, "phoenix"],
"ratings": {"strength": 2, "easiness": 5}
}
)
As expected, output will be:
WriteResult({ "nInserted": 1 })
Query on Array value
Array values are treated individually, which means we can query them by specifying the field of the array and the value we’d like to find.
Let’s execute the following command:
> db.books.find({"ingredients": "phoenix"})
In the above command, we are trying to find a book with one of the ingredients as phoenix. Output will be:
{
"_id": "ObjectId(...)",
"name": "Harry Potter",
...
"ingredients": ["chamber", 21, "phoenix"]
}
As shown, book contains one of the ingredients as phoenix.
Query on Embedded document
We can search for books by their ratings using dot notation to specify the embedded field we’d like to search. Currently, our book looks like:
{
"_id": "ObjectId(...)",
"name": "Harry Potter",
...
"ratings": {"strength": 2, "easiness": 5}
}
We can access ratings strength as ratings.strength, as shown below:
> db.potions.find({"ratings.easiness": 5})
Validating Insertion Data
MongoDB will only enforce a few rules, which means we’ll need to make sure data is valid client-side before saving it.
Basically, three rules are enforced. They are:
- No other document shares same _id
- No syntax errors
- Document is less than 16mb
This means, if we try to insert following document into our database,
> db.books.insert({
"name": "Harry Potter",
"vendor": "BlackSim",
"price": "Ten dollars",
"score": 59
})
Output will be:
WriteResult({ "nInserted": 1 })
Even when the ‘price’ field is inserted as a String, it is still reported NO ERRORS and the document still got saved to the database !!!
Delete a Single Document
The remove() collection method will delete documents that match the provided query.
> db.books.remove(
{"name": "Harry Potter"}
)
WriteResult({ "nRemoved": 1 })
Delete multiple Documents
The remove() collection method will delete all documents that match the provided query.
> db.books.remove(
{"name": "Harry Potter"}
)
WriteResult({ "nRemoved": 3 })
Above output shows that 3 documents were deleted.
Update a single document
We made a typo while inserting our new novel book, so let’s update the price. We can use the update() collection method to modify existing documents.
The update() method takes two parameters:
- Query parameter
- Update parameter
For an example, let’s see some simple command snippet:
> db.potions.update(
{
"name": "Goblet of Fire" // Query by name
},
{
"$set": { "price": 3.99 } // Update price parameter
}
)
“set” is an operator and operators always start with a “$”. Also, updates will only be applied to FIRST MATCHING document.
Output we get on execution of above command will be:
WriteResult({
"nMatched": 1, // Number of documents matched
"nUpserted": 0, // Number of documents created
"nModified": 1 // Number of documents modified
})
Updating without an operator
If the update parameter consists of only field/value pairs, then everything but the _id is replaced in the matching document.
Let’s understand this with an example. Below command will show all documents available in books collection:
> db.books.find()
Output will be :
{
"name": "Harry Potter",
"vendor": "BlackSim",
"price": 10.99,
"score": 59,
"tryDate": new Date(2012, 8, 13),
"ingredients": ["chamber", 21, "phoenix"],
"ratings": {"strength": 2, "easiness": 5}
}
If we now update price without an operator using below command:
> db.potions.update(
{ "name": "Goblet of Fire" },
{ "price": 3.99 } // No operator, just field/value pair
)
If we again try showing all data, we will get:
{
"price": 10.99
}
Clearly, all the data apart from the update field has been removed.
Update multiple documents
The update method can take a third parameter for options.
> db.potions.update(
{ "vendor": "BlackSims" },
{ "$set": { "vendor": "Black Sim" }},
{ "multi": true } //Specifying that multiple documents should be updated
)
Output can be:
WriteResult({
"nMatched": 4, // Number of documents matched
"nUpserted": 0, // Number of documents created
"nModified": 4 // Number of documents modified
})
Increment existing Integer data
Time to start analyzing which books are viewed the most. To do this, we need to record each book’s page view.
Let’s assume we have a field as ‘count’ in our documents and each document looks roughly like this:
{
"_id": ObjectId(...),
"potion": "Order of Phoenix",
"count": 1
}
We can use the $inc operator to increment the count of an existing log document. Let’s write a command for the operation:
> db.books.update(
{ "name": "Order of Phoenix" },
{ "$inc": { "count": 1 } }
)
It is interesting to note that if the field doesn’t exist, it will be created with the same value.
If we run the update on a book that doesn’t exist, then nothing will happen. For example, let’s update a book which doesn’t exist yet,
> db.books.update(
{ "name": "Full Blood prince" },
{ "$inc": {"count": 1} },
)
Output will be:
WriteResult({
"nMatched": 0, // Number of documents matched
"nUpserted": 0, // Number of documents created
"nModified": 0 // Number of documents modified
})
No errors.
Find or Create With Upsert
The upsert option either updates an existing document or creates a new one. So, following command will create a book if it doesn’t exist yet,
> db.logs.update(
{ "name": "Full Blood prince" },
{ "$inc": {"count": 1 }},
{ "upsert": true }
)
Output will be:
WriteResult({
"nMatched": 0,
"nUpserted": 1,
"nModified": 0
})
So, the command creates a document using the values from the query and update parameter.
Updating once more
If we run the same command to update, the update will act normally and upsert won’t create another document.
> db.logs.update(
{ "name": "Full Blood prince" },
{ "$inc": {"count": 1 }},
{ "upsert": true }
)
Output will be:
WriteResult({
"nMatched": 1,
"nUpserted": 0,
"nModified": 1
})
Recent Stories
Top DiscoverSDK Experts
Compare Products
Select up to three two products to compare by clicking on the compare icon () of each product.
{{compareToolModel.Error}}
{{CommentsModel.TotalCount}} Comments
Your Comment