Introduction to MongoDB

MongoDB is an open-source document-oriented database which is very different from relational databases such as MySQL.

Relational databases store data in relations called tables formed by rows (records) and columns. To define these tables we need to predefine schemas. By using schemas we provide fixed rules to our tables, so it becomes very hard to adapt our database to dynamic requirements in large applications.

To solve this problem we have a different type of database called a document-oriented database, where data structure does not need to be previously defined because schemas do not exist. In this database, data is stored using flexible JSON structures (MongoDB uses BSON) so elements can have different size.

Big companies such as Facebook, Google or Ebay are using these types of databases because they can scale easier than strict relational databases. With this guide, we will start getting into document-oriented databases with MongoDB by learning how to install it (if you don’t already have it installed), configuring MongoDB for your needs, and we will also go over some of the most common operations so you can get a feel for how it works.

TERMINOLOGY

With classical relational databases, we are familiar with terms like record, table, views, etc. In MongoDB this changes a little bit, but some of it remains very similar.
Information in relational databases are stored in tables. These tables have rows called records and each one stores data according to a defined table structure. In document-oriented databases, such as MongoDB, data is stored in documents, and multiple documents make a collection.

DOCUMENTS

A document in MongoDB is essentially an object composed by pairs key/value (similar to JSON and called BSON). The value of a field can be any BSON type, including other documents, arrays and arrays of documents. We’ll see an example in just a brief moment.

Unlike in SQL, field types are more closely related to well-known application types. For example, SQL provides us a few types for storing strings (varchar, char, blob, text, etc), but MongoDB on the other side just gives us “String” as a type.

One specific field type of MongoDB is an ObjectId. The ObjectId type provides us with an identifier for our documents and makes them unique (there is an interesting talk about ObjectId uniqueness on Stack Overflow) similar to the autoincrement field used in SQL.

Let’s see an example of a MongoDB document:

{
    "_id" : ObjectId("57ea50bff0333f6b6e32a451"),
    "email" : "hello@mycompany.com",
    "username" : "mycompany",
    "name" : "My Company",
    "created_at" : ISODate("2016-09-27T10:40:02.081Z"),
    "capabilities": ["can_add_post", "can_add_users"]
}

This document has a unique identifier similar to the classical autoincrement field called _id and a couple of fields with typical information about a profile.

Every MongoDB document requires a unique _id field that acts as a primary key. MongoDB uses ObjectId type for this field by default, and documents will contain an ObjectId _id field on insert if not specified, so you do not have to worry about it when adding new documents to your database.

INSTALLING MONGODB ON UBUNTU 16.04

Even though MongoDB is included in Ubuntu package repositories, they recommend us to use their repository in order to have the most updated version.

Ubuntu guarantees the authenticity of their packages by using the package’s distributor public key, so we need to import the MongoDB public key first using the following command:

sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 0C49F3730359A14518585931BC711F9BA15703C6

Then we add their repository to our Ubuntu repositories list:


echo "deb [ arch=amd64,arm64 ] http://repo.mongodb.org/apt/ubuntu xenial/mongodb-org/3.4 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-3.4.list

Now, we need to reload our local package database so Ubuntu can use our new repository when we look for the MongoDB package:

sudo apt-get update

And finally we just install it by using the apt command:

sudo apt-get install -y mongodb-org

If everything goes well, MongoDB should be installed and automatically running as a service. To check if MongoDB is running correctly, we can execute the following command:

service mongod status

And it should return something like:

mongod start/running, process 8247 
If MongoDB service is not running, you should start it using:
service mongod start


SETTING MONGODB

MongoDB has a configuration file where we can define parameters like a default port, folder where the database will be stored, etc. By default, this file is located in the /etc directory if we install it like we did, but we can create it in some other place and load it using --config parameter:

mongod --config path/to/mongod.conf

NOTE: If we are using MongoDB as a service, we have to modify our system’s init script (for example, /etc/init.d/mongodb) in order to load the new configuration file.

This configuration file contains a lot of parameters, and you will have to tweak them depending on your application needs. Some of them are:

  • dbpath: MongoDB stores its databases inside a folder, so here you can specify where you want to store the data.
  • port: TCP port on which MongoDB listens to connections (Default: 27017).   
  • path: path to the MongoDB log file.
  • verbosity: log message verbosity from 0 (default) to 5.

You can also override these parameters for testing by invoking MongoDB using the mongod command (you have to make sure that MongoDB is not running as a service). For example, if we want MongoDB to load a  database from our/db path on port 47017, we can use:

sudo mongod --dbpath our/db --port 47017

Note: you can add an ampersand at the end so the process will run in background.

If you need further help with all of the parameters and their values, take a look at all parameters in MongoDB documentation. 


MONGODB SHELL

The mongo shell is a powerful tool to interact directly with your MongoDB database (pretty similar to the MySQL command line tool). If you install MongoDB using the previous method, type mongo directly in your  terminal:

mongo

If you receive a “Command not found” message, you need to go directly to your MongoDB installation folder and initialize it from there. A more comfortable option is to add MongoDB installation folder to the PATH environment variable, so you will be able to start the mongo shell from any place.

To do this, open your bashrc file located under your user’s main directory (you can use your favorite editor, you don’t have to use vim):

vim ~/.bashrc

And add the following at the end of the file (where <mongo dir> should be your MongoDB installation folder) and save:

export PATH=<mongo dir>/bin

Now if you open a new terminal and type mongo, the mongo shell should be start. 


OPTIONS

The mongo shell will attempt to connect to our MongoDB instance running on localhost on port 27017 by default, but we can specify different parameters if we need to. 

For example, if our instance is running on port 47017 and host db.ourmachine.com, we should start mongo shell like this:

mongo --host db.ourmachine.com --port 47017

We can also use authorization by passing user and password parameters:

mongo -u my_db_user -p my_db_password --host db.ourmachine.com --port 47017

If you need advanced parameters, you should check the mongo shell documentation. 


FIRST STEPS WITH MONGO SHELL

To use this shell, you need to go to a database first so you can start doing operations on its collections. To display the database you are using, type db: 

> db

Note: If we do not specify, the default database will always be test.

To list our databases, we use show dbs command: 

> show databases
admin      (empty)
project-stage    0.153GB
project-master  0.635GB
local      0.078GB

Now we are going to do some operations on our project-stage database. To start using it, we type:

> use project-stage
switched to db project-stage

One of the best things about MongoDB is that you can switch to non-existing databases. So if you need to create a new database you can use the use <db-name> command. In our case the project-stage database was already created, otherwise an empty database with that name would be created.


CRUD OPERATIONS

We can perform CRUD operations (CRUD is an acronym for Create, Read, Update, Delete) on our MongoDB documents. All operation commands always follow this pattern: 

db.<collection>.<operation>(<query>, <command-options>)

Before applying any operation on a collection, you should switch to your desired database using use <db_name> command.


EXAMPLE DATABASE

In the following sections we are going to explain how to perform operations on our documents. We will use a library database with only one collection for storing books. One example of a book document could be:

{
  _id:   ObjectId(507f191e810c19729de860ea),
  title:  “The Lord of the Rings”
  author:  “J. R. R. Tolkien”,
  isbn: 9780071278898,
  reviews:  5,
  category:  [“fiction”, “epic”]
}

QUERY DOCUMENTS

One of the most basic operations indatabases is “give me something based on a criteria”. In SQL we use the SELECT sentence: 

SELECT <fields> FROM <table> WHERE <condition> 

In MongoDB we have the find method that works in similar ways. For example, if we need all books from a particular author, we can do this: 

> db.books.find({ author: “Stephen King” })

This method expects a JSON with key/value pairs to compare. Now if we want to list all books, we can use an empty JSON object as a parameter (we get the same result if we do not pass a parameter): 

> db.books.find({})
> db.books.find()

As you may see, query conditions are key/value pairs. This condition can also have mathematical and boolean operators.


AND OPERATION

By default our query conditions are joined by an implicit AND operation, so if we need all books from John Le Carré with five reviews: 

> db.books.find({ author: “John Le Carré”, reviews: 5 })

OR CONDITION

We can create queries which join multiple clauses with a logical OR conjunction by using the $or operator. This operator will get an array of clauses and creates the logical OR.

For example, to get all books written by Stephen King or with five reviews, we do the following:

> db.books.find({ $or: [ {author: “Stephen King”}, {reviews: 5} ]}

AND / OR OPERATIONS COMBINED

We can combine multiple AND and OR operations to create complex queries. For example, if we need books written by “Ken Follet” with three or five reviews:

> db.books.find({
  author: “Ken Follet”,
  $or: [ {reviews: 3}, {reviews: 5} ]
})

COMPARISON OPERATORS

MongoDB provides us with a few operators to compare results with a notation similar to an assembler language. 

  • $eq: Matches values equal to value
db.books.find({ reviews: { $eq: 4 } })

Get all books with 4 reviews

  • $gtMatches values greater than value
db.books.find({ reviews: { $gt: 4 } })

Get all books with more than 4 reviews

  • $gteMatches values greater or equal than value
db.books.find({ reviews: { $gte: 4 } })

Get all books with four or more reviews

  • $ltMatches values less than value
db.books.find({ reviews: { $lt: 4 } })

Get all books with less than 4 reviews

  • $lteMatches values greater than value
db.books.find({ reviews: { $lte: 4 } })

Get all books with four or less reviews

  • $neMatches values not equal to value
db.books.find({ reviews: { $ne: 4 } })

Get all books which do not have 4 reviews

  • $inMatches any values in an array
db.books.find({ category: { $in: [ “fiction”, “terror” ] })

Get all books from either fiction or terror category

  • $ninMatches none of the values in an array
db.books.find({ category: { $nin: [ “fiction”, “terror” ] })

Get all books from categories different from fiction or terror.


UPDATE DOCUMENTS

Updating documents in MongoDB uses almost the same structure as the find method seen previously: a query to filter and the new values.

MongoDB gives us a new operator called $set to specify new values for fields. For example, if we want to update the title of all books called “Lord of the Rings”, we can do the following:

> db.books.update({ title: “Lord of the Rings” }, { $set: { title: “LOTR” } })

We can also concatenate all fields we want. For example, if we want to update the title and author of all Stephen Kings books:

> db.books.update({ author: “Stephen King” }, { $set: { title: “Some book from SK” }, { author: “Richard Bachman” } } })

This will update only the first document that matches the title criteria. This behavior should be kept in mind when doing updates. By default, the update() method updates only the first matched document. If we want an update on multiple documents we have to specify a third parameter like this:

> db.books.update({ author: “Stephen King” }, { $set: { title: “Some book from SK” }, { author: “Richard Bachman” } } }, { multi: true })

One recommendation should be to use updateOne() when we want to update only the first matched document: 

> db.books.updateOne({ title: “Lord of the Rings” }, { $set: { title: “LOTR” } })

Or use updateMany() method when we want to update multiple documents: 

> db.books.updateMany({ title: “Lord of the Rings” }, { $set: { title: “LOTR” } })

This is similar to using LIMIT 1 in SQL. This way we will not make mistakes by forgetting a parameter which would produce undesirable results.


INSERT DOCUMENTS

One of the peculiarities of MongoDB is that we do not need a created collection to insert a document. MongoDB takes care of this and if the collection doesn’t exist, it will create both the collection and document. This behavior removes some headaches when working with fresh databases because we do not need to check for collection existence.

In MongoDB we can insert one document or multiple documents at the same time. For example, to insert a new book into our collection:

> db.books.insert({
  title: “The silence of lambs”,
  author: “Thomas Harris”,
  ISBN: 8285071273094,
  reviews: 0,
  category: [“suspense”, “terror”]
})

You can notice that we do not specify the _id field. As we said before, _id field is automatically filled by MongoDB with a unique ObjectId value.

If we want to insert multiple books, we should pass it as an array like this:

> db.books.insert([
  {
    title: “The silence of lambs”,
    author: “Thomas Harris”,
    ISBN: 8285071273094,
    reviews: 0,
    category: [“suspense”, “terror”]
  },
  {
    title: “The Black Dahlia”,
    author: “James Ellroy”,
    ISBN: 9780446698870,
    reviews: 0,
    category: [“mistery”, “police”]
  },
])

You can also use insertOne() method to insert only one document, or insertMany() to insert multiple documents.


DELETE DOCUMENTS

To delete a document from a collection in MongoDB, we use the remove() method. For example, if we want to remove all Stephen King books:

> db.books.remove({ author: “Stephen King” })

This will delete all documents that matches the criteria. If we only want to remove the first matched document, we have to specify a second argument:

> db.books.remove({ author: “Stephen King” }, { justOne: true })

This is very important to know because by default it will remove all documents (if you remember, the update method works by updating only the first if we do not specify the opposite).

So to avoid undesirable deletes, we encourage to use deleteOne() and deleteMany() instead. They are more readable and work the same as remove(). So if we wanted to remove only the first matched document:

> db.books.deleteOne({ author: “Stephen King” })

And if we wanted to remove all of them:

> db.books.deleteMany({ author: “Stephen King” })

MONGODB ADMIN CLIENTS

The mongo shell provides you all you need to work directly with your MongoDB instance, but for the day-to-day it could be better to have a graphical tool to see all records and execute CRUD operations. 

There are tons of clients to work with MongoDB. One of the best is Robomongo, a very interesting cross-platform client to manage our MongoDB database in an easy way. 

To start using it, we have to download it from their official webpage (it’s free for personal use) and install it. After that, we need to setup a new connection so we go to File > Connect and we will see a window like this:

user_54364_5818f39200613.png

Then we press on Create link and specify our connection settings (host, port, authentication, etc). By default it is already set to a non authenticated connection on localhost on port 27017 (we can press “Test” to check if a connection can be made). 

After pressing the “Connect” button we will see a tree view of every database with all collections included. We can double-click on them to see documents and use the above input text to perform any mongo operation we want.

user_54364_5818f39d97e4e.png_800.jpg

With Robomongo you can also do specific operations using a graphic interface (like removing documents with two clicks, or inserting a new one by filling a BSON structure) and have multiple connections to different instances at the same time. Robomongo is a handy tool to do some heavy work with a MongoDB instance.


CONCLUSION

  1. We have learned how to install MongoDB on Ubuntu.
  2. We have learned new terminology and how MongoDB organizes data (database, collection, document).
  3. We have looked at MongoDB CRUD operations with its shell.
  4. We have discovered a tool to manage and interact with our MongoDB instance called Robomongo.

WHAT'S NEXT?

This was an introductory guide for people that came from SQL environments and want to give MongoDB a try. There are many other important aspects like indexing, document relationships (documents can be related by embedding one into another or referenced by their _id field), profiling, exporting/importing databases, etc.

  • post-author-pic
    Terrence C
    11-02-2016

    Fantastic guide - thanks for the contribution!

  • post-author-pic
    Thomas H
    11-02-2016

    Awesome! Thanks for contributing, Francisco!

  • post-author-pic
    Manisha S
    11-02-2016

    Very well organized and explained! Thanks Francisco for your awesome contribution!

  • post-author-pic
    Francisco S
    11-02-2016

    Thanks team! Glad you like it! :D

  • post-author-pic
    Kurt M
    11-08-2016

    Great guide, Francisco!

  • post-author-pic
    Raül M
    01-14-2017

    Nice work!

  • post-author-pic
    Francisco S
    01-16-2017

    Thank you so much!   @kmaine    @raulmartinezydiaz 

  • post-author-pic
    Aman S
    02-02-2017

    Thanks, wonderful article !!

  • post-author-pic
    Prakyath R
    02-02-2017

    Great guide!! I already bookmarked it..

  • post-author-pic
    Francisco S
    02-03-2017

    Thanks! If you have some suggestions or improvements, let me know :)

  • post-author-pic
    Andrzej K
    07-10-2017

    Hello, There are some mistakes here. Installation is not working, I have to use official  MongoDB website. No sample inserts to be able to test the code. Code has many mistakes for example place of comparison operators. Update statement not working.  

  • post-author-pic
    Francisco S
    07-10-2017

    Hi  @andrzej . This guide was written a few months ago, so installation steps might be not work for current stable version. I will update it as soon as possible. 

  • post-author-pic
    Andrzej K
    07-10-2017

    Hello @Francisko,  Thanks a lot for quick replay. I suggest to add sample script to generate database with some books inside (maybe put insert at the beginning of ontro) a little bit explanation what is db and dbs I do not see a differences, then examples of CRUD on sample databases to be easy to follow. I see for sure error with operator syntax, correct one: db.books.find( { reviews: { $gt: 4 } } )

  • post-author-pic
    Francisco S
    07-27-2017

    I've updated MongoDB installation instructions according to MongoDB official doc. I also changed operators syntax.

  • post-author-pic
    Manikanta S
    09-07-2017

    I would like to do certification course on MongoDB. Is there any course in LinuxAcademy or can you refer any best place to learn & practice ?

  • post-author-pic
    Francisco S
    09-11-2017

    Hi  @manirgm448 ,

    LA staff always track students suggestions about new courses and guides. Maybe they will add it in a future, but for now I don't think that they have plans for that kind of technology :)

    Thanks for commenting!

Looking For Team Training?

Learn More