Lesson 5 - Introduction to MongoDB
In the previous lesson, Complete RESTful API in Node.js, we implemented a complete RESTful API with Express. But we stored data only in an array, so we lost it every time we restarted the application. Therefore, it'd be useful to have a database in the project where the data would be stored permanently.
Choosing the Database
We can choose from many available databases. On the one hand, we have relational databases (MySQL, MS-SQL, and other) that use tables and we query data using SQL statements. However, non-relational or document-oriented databases are more popular for Node and Express projects. The best known is MongoDB.
MongoDB
MongoDB is a NoSQL database. It's object-oriented, simple, dynamic and well scalable. It uses collections instead of tables (as in a relational database), instead of rows and columns it uses documents and fields. The data is stored in the JSON format, which is useful because we already have our data in the JSON format, and we won't have to convert it anyhow. (More precisely, they are stored on the disk as BSON, which is a binary JSON - but this is not very important.) The data don't have any predefined format (MongoDB is said to be schema-less). Objects can be nested in each other, so what you'd have to do with multiple linked tables in a relational database can be done in a single document in MongoDB.
Installation
On the https://www.mongodb.com page,
click Try Free
at the top right and select the server tab. You
should have the MongoDB Community Server selected. Next, select the version (or
leave the selected one) and select your operating system. Leave the package as
MSI and download the installer. Select the complete installation type. Somewhen
during the installation, the installer will ask if you want to install MongoDB
Compass. You definitely want it, but sometimes it can be a problem to install it
together with the database - if that happens, install the database without it
and then install it separately. It can be found at the same page in the Tools
tab.
The MongoDB homepage often changes, so everything may not match exactly, but downloading should always be easy. To begin with, you want the MongoDB Community Server and to install MongoDB Compass as well.
Now, move to the C:\Program Files\MongoDB\Server\4.0\bin
folder
in the command line (customize the version according to the current version of
your installation) and run MongoDB with the mongod
command:
cd C:\Program Files\MongoDB\Server\4.0\bin mongod
To make it easier to use, it pays off to add the above path to the
PATH
variable in environment variables. The steps varies according
to your Windows version, in Windows 10 it's in Control Panel -> System and
Security -> System -> View advanced system settings. Next, click on the
environment variables, find the PATH
variable, click Edit ...,
click New, and add the path to Mongo. Then just click Ok three times. You should
now be able to run the mongodb
command from anywhere. (If you set
it up correctly and it still doesn't work, try restarting the command line.)
When you start Mongo, it'll print quite a lot of things, and if you've never
had Mongo on your computer before, it'll probably throw an exception. It'll be
about four lines before the end of the output and will contain something like
NonExistentPath: Data directory C:\data\db\ not found., terminating
.
This is because Mongo stores its data in the C:\data\db
directory
by default. Let's create it:
md c:\data\db
Run mongo again, it should run fine now, and the last message should be that
it's waiting on the port 27017
.
Run installed Compass, click yourself through "Next" and "Get Started", leave
the default settings (i.e. localhost
and the port
27017
) on the connection page and connect. You should see the
default Mongo databases (certainly admin
and local
,
possibly config
).
Mac Installation Notes
On Mac, you can simplify the installation with Homebrew. Homebrew is a
package manager (something like npm) for macOS and Linux. Follow the
instructions at https://brew.sh/
to install it. Now you can install
Mongo with a simple brew install mongodb
command. Be sure to create
the database directory and to install Compass.
Alternative Solution
If you don't want, you don't need to download Mongo at all. There's also DBaaS (database as a service), where you can use a platform to offer you a hosted database.
We can use MLab (mlab.com
) with various packages available, the
trial package (which is enough for our first projects) is free.
Also, Mongo now offers the Atlas cloud service, where you can also host your databases for free. It can be found directly on the Mongo main page. If you try it, you can write your experiences in the comments, and I'm curious about them.
Connecting to the Database
Let's start a new project. We'll install the mongoose
package
into it. Thanks to mongoose
we'll be able to work with Mongo
through a simple API:
mkdir mongo-project cd mongo-project npm init --yes npm install mongoose
Create the index.js
file and paste the following code into
it:
const mongoose = require('mongoose'); mongoose.connect('mongodb://localhost:27017/moviesdb', { useNewUrlParser: true }) .then(() => console.log('Connected to MongoDB!')) .catch(error => console.error('Could not connect to MongoDB... ', error));
First, we load the mongoose
module and store it as a constant
containing an object. This object has the connect()
method that
allows us to connect to the database. It takes the connection string as the
first parameter. We hard-coded it for now. In a real application, you'll rather
read the connection string from the configuration file. This will be
mongodb://localhost:27017/moviesdb
, where moviesdb
is
the database name.
The fact that our database doesn't yet exist doesn't matter at all. MongoDB creates it the first time we connect to it.
The second parameter is only configuration for newer Mongo versions (> = 3.1.0).
Because the connect()
method returns a promise (see the note at
the end of the article), we can call then()
on it to react on a
successful call and catch()
to react to an error.
We now just run the project (node index.js
), and we should see a
successful connection message if everything went OK.
Next time, in the lesson First steps in MongoDB, we'll talk a little bit more about
mongoose
and show you how to write and read data using it.
Final note: Promises
Since ES6 promises are often use to handle asynchronous calls in
JavaScript. Promise is a promise of some future value. Connecting to a database
is an example of an asynchronous operation (it takes a while to connect, so we
don't know the result right away, and we must wait for it - but thanks to
asynchronicity, other code can normally run while waiting). Promise
is one way to deal with this (another would be the async/await
syntax which we'll use next time).
Promise
can be in three states - pending, fulfilled and
rejected. It also has the then()
method which takes a function as a
parameter - it's called if the promise succeeds. There's also the
catch()
method, whose parameter (also a function) is called in case
of rejection, i.e. of an error.