Introduction
As today the Popularity of handheld devices are growing at an incredible pace. Database sizes for small applications need to store more data than many databases were meant to handle. As the amount of data that developers need to store grows, developers difficulty for scaling their databases is also growing. Either they should go for scale-up (i.e getting a bigger machine) or scale-out (partitioning data across more machines). We can scale-up upto a certain limit because large machines are expensive, and physical limit can be reached where a more powerful machine cannot be purchased at any cost. So we need to go for scale-up option for our databases.
MongoDB was designed from the beginning to scale out. Its document-oriented data model allows it to automatically split up data across multiple servers. It can balance data and load across a cluster, redistributing documents automatically. MongoDB tries to simplify database administration by making servers administrate themselves as much as possible
Getting started with MongoDB
MongoDB is a document-oriented database, not a relational one. Non relational means it does not store data in tables but in the form of JSON document. The primary reason for moving away from the relational model is to make scaling out easier. Here in MongoDB row is replaced with document and table is replaced with collection. It can be thought of as a group of documents.
Document is the basic unit of data for MongoDB, roughly equivalent to a row. It is a data structure composed of field and value pairs. MongoDB documents are similar to JSON objects. The values maybe documents, arrays, and arrays of documents.
{
"name": "binit",
"age": "24",
"subject": ["mathematics", "science", "litrature"]
}
Features of MongoDB
Indexing
MongoDB supports generic secondary indexes, allowing a variety of fast queries, and provides unique, compound, and geospatial indexing capabilities as well.
Stored JavaScript
Instead of stored procedures, developers can store and use JavaScript functions and values on the server side.
Aggregation
MongoDB supports MapReduce and other aggregation tools.
Schemaless
MongoDB documents are Schemaless This gives developers a lot of flexibility in how they work with evolving data models.
Install MongoDB
Now i will show you how to install MongoDB on mac/linux.
Steps.
- Go to http://www.mongodb.org/downloads and download
- Go into the download directory of your MongoDB
- Type tar vxf <file name> . It will extract the contents of tar and create a directory of name mongo..
- Enter mongo../bin directory and type ls you will see mongo and mongod. mongo is MongoDB shell which will connect the database to run commands mongod is the MongoDB server
- By default mongodb puts its data in /data/db directory so create it using sudo mkdir -p /data/db
- Assign permision to data/db directory using chmod 777 /data/db so that everybody can use it. Its only good in development environment
- Start MongoDB server using ./mongod
- Now start your mongo shell in new tab using ./mongo
Use MongoDB Shell
MongoDB shell is type of JavaScript shell that interacts with a MongoDB instance from the command line. Shell automatically attempts to connect to a MongoDB server on startup, so make sure you start mongod before starting the shell. On startup, it connects to the test database on a MongoDB server and assigns this database connection to the global variable db.
>show dbs
>show collections
>show users
>use <db name>
CRUD Operation
We can use the four basic operations, create, read, update, and delete (CRUD), to
manipulate and view data in the shell.
Create
The insert function adds a document to a collection. For example, suppose we want to store a student information. First, we’ll create a local variable called student that is a JavaScript object representing our document. This object is a valid MongoDB document, so we can save it to the school collection using the insert method:
> student = { "name":"binit", "age": 24, "subjects": ["math", "science", "litrature"] }
{
"name" : "binit",
"age" : 24,
"subjects" : [
"math",
"science",
"litrature"
]
}
> db.school.insert(student)
WriteResult({ "nInserted" : 1 })
> student1 = { "name":"ashok", "age": 28, "subjects": ["math", "science", "litrature"] }
{
"name" : "ashok",
"age" : 28,
"subjects" : [
"math",
"science",
"litrature"
]
}
> db.school.insert(student1)
WriteResult({ "nInserted" : 1 })
>
Read
If we just want to see one document from a collection, we can use findOne()
method
> db.school.findOne()
{
"_id" : ObjectId("54396f072a17974b75791f26"),
"name" : "binit",
"age" : 24,
"subjects" : [
"math",
"science",
"litrature"
]
}
> db.school.findOne({"name":"binit"})
{ "_id" : ObjectId("54396f072a17974b75791f26"), "name" : "binit", "age" : 24, "subjects" : [ "math", "science", "litrature" ] }
As you can see there is a new field called '_id' whose value seems to be something ObjectId("54396f072a17974b75791f26")
consisting of some alpha numeric sequence. When you insert document into MongoDB the server requires all document to have unique identifying field. That's why it creates _id field inside each document. It acts as a primary key for the document. While creating this object id MongoDB takes into account current time + identification no for machine that is creating the object id + process id + counter
> db.school.findOne({"name":"binit"}, {"name": true})
{ "_id" : ObjectId("54396f072a17974b75791f26"), "name" : "binit" }
> db.school.findOne({"name":"binit"}, {"name": true, "_id":false, "age":24})
{ "name" : "binit", "age" : 24 }
If you want to see all documents of a collection then you can use find()
method. If a collection has many rows and you are runing queries in mongo shell then it will retrive rows in batches of 20 by default. you can retrive more by typing >it
> db.school.find()
{ "_id" : ObjectId("54396f072a17974b75791f26"), "name" : "binit", "age" : 24, "subjects" : [ "math", "science", "litrature" ] }
{ "_id" : ObjectId("54396f702a17974b75791f27"), "name" : "ashok", "age" : 28, "subjects" : [ "math", "science", "litrature" ] }
You can also use pretty()
method to get rows in more readable way.
> db.school.find().pretty()
{
"_id" : ObjectId("54396f072a17974b75791f26"),
"name" : "binit",
"age" : 24,
"subjects" : [
"math",
"science",
"litrature"
]
}
{
"_id" : ObjectId("54396f702a17974b75791f27"),
"name" : "ashok",
"age" : 28,
"subjects" : [
"math",
"science",
"litrature"
]
}
find()
method also takes arguments. First argument specifies what document to return in query, just like where clause in SQL
> db.school.find({"age":24})
{ "_id" : ObjectId("54396f072a17974b75791f26"), "name" : "binit", "age" : 24, "subjects" : [ "math", "science", "litrature" ] }
you can specifiy more criteria to search for document like this
> db.school.find({"age":24, "name":"binit"})
{ "_id" : ObjectId("54396f072a17974b75791f26"), "name" : "binit", "age" : 24, "subjects" : [ "math", "science", "litrature" ] }
Just like findOne()
method find()
method also takes 2nd argument to specify what fields to retrive, just like select clause in SQL
> db.school.find({"name":"binit"}, {"name": true, "_id":false, "age":24})
{ "name" : "binit", "age" : 24 }
Querying using $gt and $lt operators
> db.school.find({"age":{$gt: 20}})
{ "_id" : ObjectId("54396f072a17974b75791f26"), "name" : "binit", "age" : 24, "subjects" : [ "math", "science", "litrature" ] }
{ "_id" : ObjectId("54396f702a17974b75791f27"), "name" : "ashok", "age" : 28, "subjects" : [ "math", "science", "litrature" ] }
> db.school.find({"name":{$gte: "a"}})
{ "_id" : ObjectId("54396f702a17974b75791f27"), "name" : "ashok", "age" : 28, "subjects" : [ "math", "science", "litrature" ] }
> db.school.find({"age":{$gt: 25, $lte: 30}})
{ "_id" : ObjectId("54396f702a17974b75791f27"), "name" : "ashok", "age" : 28, "subjects" : [ "math", "science", "litrature" ] }
> db.school.find({"age":{$lt: 25}})
{ "_id" : ObjectId("54396f702a17974b75791f27"), "name" : "ashok", "age" : 28, "subjects" : [ "math", "science", "litrature" ] }
Using $regex and $exists operator
> db.school.find()
{ "_id" : ObjectId("54396f072a17974b75791f26"), "name" : "binit", "age" : 24, "subjects" : [ "math", "science", "litrature" ] }
{ "_id" : ObjectId("54396f702a17974b75791f27"), "name" : "ashok", "age" : 28, "subjects" : [ "math", "science", "litrature" ] }
{ "_id" : ObjectId("543992f72a17974b75791f28"), "name" : "nitish", "age" : 28 }
{ "_id" : ObjectId("543993392a17974b75791f29"), "name" : "ansuman", "age" : 28, "subjects" : "math" }
> db.school.find({subjects: {$exists: true}})
{ "_id" : ObjectId("54396f072a17974b75791f26"), "name" : "binit", "age" : 24, "subjects" : [ "math", "science", "litrature" ] }
{ "_id" : ObjectId("54396f702a17974b75791f27"), "name" : "ashok", "age" : 28, "subjects" : [ "math", "science", "litrature" ] }
{ "_id" : ObjectId("543993392a17974b75791f29"), "name" : "ansuman", "age" : 28, "subjects" : "math" }
> db.school.find({name: {$regex: "a"}})
{ "_id" : ObjectId("54396f702a17974b75791f27"), "name" : "ashok", "age" : 28, "subjects" : [ "math", "science", "litrature" ] }
{ "_id" : ObjectId("543993392a17974b75791f29"), "name" : "ansuman", "age" : 28, "subjects" : "math" }
Using $or operator
> db.school.find({$or: [{"name": "binit"}, {"age": {$gte:28}}]})
{ "_id" : ObjectId("54396f072a17974b75791f26"), "name" : "binit", "age" : 24, "subjects" : [ "math", "science", "litrature" ] }
{ "_id" : ObjectId("54396f702a17974b75791f27"), "name" : "ashok", "age" : 28, "subjects" : [ "math", "science", "litrature" ] }
{ "_id" : ObjectId("543992f72a17974b75791f28"), "name" : "nitish", "age" : 28 }
{ "_id" : ObjectId("543993392a17974b75791f29"), "name" : "ansuman", "age" : 28, "subjects" : "math" }
Querying inside array
> db.school.find({"subjects": "math"})
{ "_id" : ObjectId("54396f072a17974b75791f26"), "name" : "binit", "age" : 24, "subjects" : [ "math", "science", "litrature" ] }
{ "_id" : ObjectId("54396f702a17974b75791f27"), "name" : "ashok", "age" : 28, "subjects" : [ "math", "science", "litrature" ] }
{ "_id" : ObjectId("543993392a17974b75791f29"), "name" : "ansuman", "age" : 28, "subjects" : "math" }
Using $in operator
> db.school.find({"name": {$in : ["binit", "ansuman"]} })
{ "_id" : ObjectId("54396f072a17974b75791f26"), "name" : "binit", "age" : 24, "subjects" : [ "math", "science", "litrature" ] }
{ "_id" : ObjectId("543993392a17974b75791f29"), "name" : "ansuman", "age" : 28, "subjects" : "math" }
Update
An update()
method takes atleast two arguent, first argument is the query where we want to make update in collection which is the where clause of SQL and 2nd argument is the document. Whatever you put inside that document will replace everything except the primary key of the document being updated
> db.school.find({"name": "nitish"})
{ "_id" : ObjectId("543992f72a17974b75791f28"), "name" : "nitish", "age" : 28 }
> db.school.update({"name": "nitish"}, {"name": "nitishk", "profession": "student"})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.school.find({"name": "nitishk"})
{ "_id" : ObjectId("543992f72a17974b75791f28"), "name" : "nitishk", "profession" : "student" }
This update()
method is very dangerous because of its nature of complete replacement of document. So dont use it unless you are sure of what you doing.
Using $set operator
$set operator dont replace the whole document but it only replaces the key we wanted to replace, and if that is not present in that document then it will create that key. So it safe to use $set operator.
> db.school.find({"name":"binit"})
{ "_id" : ObjectId("54396f072a17974b75791f26"), "name" : "binit", "age" : 24, "subjects" : [ "math", "science", "litrature" ] }
> db.school.update({"name": "binit"}, { $set: {"age": 34}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.school.find({"name":"binit"})
{ "_id" : ObjectId("54396f072a17974b75791f26"), "name" : "binit", "age" : 34, "subjects" : [ "math", "science", "litrature" ] }
Using $unset operator
So suppose you want to remove certain field from a document, but you dont know all other fields in that document then you can use $unset
operator. This is generally used for schema change manipulation.
> db.school.find({"name":"binit"})
{ "_id" : ObjectId("54396f072a17974b75791f26"), "name" : "binit", "age" : 34, "subjects" : [ "math", "science", "litrature" ] }
> db.school.update({"name": "binit"}, { $unset: {"age": 1}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.school.find({"name":"binit"})
{ "_id" : ObjectId("54396f072a17974b75791f26"), "name" : "binit", "subjects" : [ "math", "science", "litrature" ] }
Upsert (Update or insert)
Now as we know update method can manipulate fileds inside document or replace an document, but it can also insert a document. Lets suppose you wantto update the age of student named "ankur" but you dont know whether a student of named ankur exist or not. If you will use general update statement, it will update the age if student ankur is found in school collection otherwise it will not do anything.
But with upsert statement if the student ankur is not present it will insert that record.
> db.school.find()
{ "_id" : ObjectId("54396f072a17974b75791f26"), "name" : "binit", "subjects" : [ "math", "science", "litrature" ] }
{ "_id" : ObjectId("54396f702a17974b75791f27"), "name" : "ashok", "age" : 28, "subjects" : [ "math", "science", "litrature" ] }
{ "_id" : ObjectId("543992f72a17974b75791f28"), "name" : "nitishk", "profession" : "student", "age" : 34 }
{ "_id" : ObjectId("543993392a17974b75791f29"), "name" : "ansuman", "age" : 28, "subjects" : "math" }
> db.school.update({"name":"ankur"}, {$set: {"age": 23}})
WriteResult({ "nMatched" : 0, "nUpserted" : 0, "nModified" : 0 })
> db.school.find()
{ "_id" : ObjectId("54396f072a17974b75791f26"), "name" : "binit", "subjects" : [ "math", "science", "litrature" ] }
{ "_id" : ObjectId("54396f702a17974b75791f27"), "name" : "ashok", "age" : 28, "subjects" : [ "math", "science", "litrature" ] }
{ "_id" : ObjectId("543992f72a17974b75791f28"), "name" : "nitishk", "profession" : "student", "age" : 34 }
{ "_id" : ObjectId("543993392a17974b75791f29"), "name" : "ansuman", "age" : 28, "subjects" : "math" }
> db.school.update({"name":"ankur"}, {$set: {"age": 23}}, {upsert: true})
WriteResult({
"nMatched" : 0,
"nUpserted" : 1,
"nModified" : 0,
"_id" : ObjectId("543a75c7c4cc213d535c1cbe")
})
> db.school.find()
{ "_id" : ObjectId("54396f072a17974b75791f26"), "name" : "binit", "subjects" : [ "math", "science", "litrature" ] }
{ "_id" : ObjectId("54396f702a17974b75791f27"), "name" : "ashok", "age" : 28, "subjects" : [ "math", "science", "litrature" ] }
{ "_id" : ObjectId("543992f72a17974b75791f28"), "name" : "nitishk", "profession" : "student", "age" : 34 }
{ "_id" : ObjectId("543993392a17974b75791f29"), "name" : "ansuman", "age" : 28, "subjects" : "math" }
{ "_id" : ObjectId("543a75c7c4cc213d535c1cbe"), "name" : "ankur", "age" : 23 }
Multi Update
Update method can affect more than one document at a time if search query matches more than one document. But by default MongoDB only updates one document even if where clause of update statement matches more than one document. It will update the first document it finds on search basis and stop. To do multiple update you have to use multi: true
> db.school.find()
{ "_id" : ObjectId("54396f072a17974b75791f26"), "name" : "binit", "subjects" : [ "math", "science", "litrature" ] }
{ "_id" : ObjectId("54396f702a17974b75791f27"), "name" : "ashok", "age" : 28, "subjects" : [ "math", "science", "litrature" ] }
{ "_id" : ObjectId("543992f72a17974b75791f28"), "name" : "nitishk", "profession" : "student", "age" : 34 }
{ "_id" : ObjectId("543993392a17974b75791f29"), "name" : "ansuman", "age" : 28, "subjects" : "math" }
{ "_id" : ObjectId("543a75c7c4cc213d535c1cbe"), "name" : "ankur", "age" : 23 }
> db.school.update({}, {$set: {"title": "Er"}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.school.find()
{ "_id" : ObjectId("54396f072a17974b75791f26"), "name" : "binit", "subjects" : [ "math", "science", "litrature" ], "title" : "Er" }
{ "_id" : ObjectId("54396f702a17974b75791f27"), "name" : "ashok", "age" : 28, "subjects" : [ "math", "science", "litrature" ] }
{ "_id" : ObjectId("543992f72a17974b75791f28"), "name" : "nitishk", "profession" : "student", "age" : 34 }
{ "_id" : ObjectId("543993392a17974b75791f29"), "name" : "ansuman", "age" : 28, "subjects" : "math" }
{ "_id" : ObjectId("543a75c7c4cc213d535c1cbe"), "name" : "ankur", "age" : 23 }
> db.school.update({}, {$set: {"title": "Er"}}, {multi: true})
WriteResult({ "nMatched" : 5, "nUpserted" : 0, "nModified" : 4 })
> db.school.find()
{ "_id" : ObjectId("54396f072a17974b75791f26"), "name" : "binit", "subjects" : [ "math", "science", "litrature" ], "title" : "Er" }
{ "_id" : ObjectId("543992f72a17974b75791f28"), "name" : "nitishk", "profession" : "student", "age" : 34, "title" : "Er" }
{ "_id" : ObjectId("543993392a17974b75791f29"), "name" : "ansuman", "age" : 28, "subjects" : "math", "title" : "Er" }
{ "_id" : ObjectId("543a75c7c4cc213d535c1cbe"), "name" : "ankur", "age" : 23, "title" : "Er" }
{ "_id" : ObjectId("54396f702a17974b75791f27"), "name" : "ashok", "age" : 28, "subjects" : [ "math", "science", "litrature" ], "title" : "Er" }
Delete
remove()
method deletes documents permanently from the database. Called with no parameters,
it removes all documents from a collection. It can also take a document specifying
criteria for removal just like find()
method.
If you will supply {"name": "ankur"} inside remove method then document with name ankur will be removed.
If you want to remove all document in single pass in more efficient manner then use drop()
method. db.collection.drop()
. The difference between droping a collection and removing all the documents of a collection is only implementation details. Removing all the documents from a collection will require one by one update of internal state of each document that exists in collection. While droping a collection will free up much larger datastructure inside of the database data file. Droping a collection is much faster and all the meta data of collection will be discarded.
> db.school.find()
{ "_id" : ObjectId("54396f072a17974b75791f26"), "name" : "binit", "subjects" : [ "math", "science", "litrature" ], "title" : "Er" }
{ "_id" : ObjectId("543992f72a17974b75791f28"), "name" : "nitishk", "profession" : "student", "age" : 34, "title" : "Er" }
{ "_id" : ObjectId("543993392a17974b75791f29"), "name" : "ansuman", "age" : 28, "subjects" : "math", "title" : "Er" }
{ "_id" : ObjectId("543a75c7c4cc213d535c1cbe"), "name" : "ankur", "age" : 23, "title" : "Er" }
{ "_id" : ObjectId("54396f702a17974b75791f27"), "name" : "ashok", "age" : 28, "subjects" : [ "math", "science", "litrature" ], "title" : "Er" }
> db.school.remove({"name": "ankur"})
WriteResult({ "nRemoved" : 1 })
> db.school.remove({})
WriteResult({ "nRemoved" : 4 })
> db.school.insert(student)
WriteResult({ "nInserted" : 1 })
> db.school.drop()
true