Remember that the M in the MEAN stack, is an open source document-based database. It's considered a NoSQL database because it doesn't use SQL and is not relational. It integrates well with JavaScript-based tools because, instead of tables, it stores data in documents that can be treated by our Node.js application as JSON.
The first step in getting MongoDB running on your system is installation. Head over to https://www.mongodb.org/downloads#production, and you will find the most updated installation download for Windows, Mac, Linux, or Solaris. There are also links to instructions there to install MongoDB with tools such as Homebrew for Mac and yum for Linux.
Up-to-date installation instructions for each operating system can be found at https://docs.mongodb.org/manual/. There are differences between the operating systems, and installation instructions may change with newer versions. I suggest following the official installation instructions.
Once installed, you can start the MongoDB service by typing mongod
in a console.
You will not be able to type any other commands in that console while the MongoDB daemon is running. By default, this process will run on port 27017
and bind to the IP address, 127.0.0.1
. Both of these can be changed with command flags at start up, or with a .conf
file. For our purposes, the defaults will do.
We'll begin to work with MongoDB with the command-line shell included with the Mongo installation. As you must have the MongoDB daemon running to work with the database, you'll need to open a new console.
In the application we are building, we will rely on Node.js plugins to handle our database operations. It is beneficial, however, to gain an understanding of how MongoDB works and how it differs from SQL databases.
The best way to do that is to get our hands dirty and run some basic operations from the command line of MongoDB's shell.
Let's select the database that we want to work with. Open your command line and enter the following command:
$mongo > use test switched to db test >
Running mongo
, as opposed to mongod
, from the command line starts the MongoDB shell, which allows typing commands directly to the running MongoDB daemon.
The use
command selects which database we are currently using. But, wait a minute; we never created a test database. That's correct, and we still haven't. We can use the showdbs
command to list all of the databases on our computer that MongoDB knows about:
> show dbs local 0.078GB
If you've done all the previous examples, you would already have created a local database name test
. Local stores a startup
log and replica information in replicated environments. We can use local and add our own data to it, but that's not really a great idea. Let's create a database of our own.
Remember that records in MongoDB are referred to as documents. They loosely relate to rows in a traditional relation database but are much more flexible.
If we insert a document now, the new database will be created use the following commands:
> db.cat.insert({name:"Tom",color:"grey"}) WriteResult({ "nInserted" : 1 }) > show dbs local 0.078GB test 0.078GB
The db.cat.insert()
command adds the document in the argument to insert to a collection called cat.
In MongoDB, a collection is a set of documents. This is similar to a table in a relational database, which is a set of records. Unlike relational databases, the documents in a collection do not have to all be the same type or have the same set of data.
You may get notices that the document we inserted looks like a plain old JavaScript object. Essentially, it is. This is one of the nice things about working with MongoDB as part of the MEAN stack—it's JavaScript from the frontend all the way to the database.
When we type showdbs
, we will see that the test database is now created. We also created a cat collection in the test database by inserting a document into it. This is something to be cautious of when working with the shell. It's easy to accidentally create unwanted databases and collections with a typo.
Now that we have a database, a collection in that database, and have inserted a document into that collection, we need to be able to retrieve the document. The most basic way to do that is using the find method of MongoDB.
Let's take a look at our document:
> db.cat.find() { "_id" : ObjectId("565c010dd9d61e2dc614181f"), "name" : "Tom", "color" : "grey" }
The db.collection.find()
method is MongoDB's basic method to read data. It is the R in MongoDB's CRUD—Create, Read, Update, Delete—operations.
As you can see, MongoDB has added an _id
field to our object, which is as follows:
> db.cat.insert({name:"Bob",color:"orange"}) WriteResult({ "nInserted" : 1 }) > db.cat.find({},{_id:0,name:1}) { "name" : "Tom" } { "name" : "Bob" }
We've inserted a new orange cat named Bob
here and, this time, the find method we're using is a little different. It's taking two arguments.
The first argument is the query criteria. This tells MongoDB which documents to select. In this case, we've used an empty object so all documents are selected.
The second argument is a projection that limits the amount of data MongoDB returns. We told MongoDB that we want the name field, but to suppress the _id
field, which will be returned by default.
In a later chapter, we will explore how to limit the number of documents returned and sort them.
Take a look at following command:
> db.cat.find({color:"orange"},{_id:0,name:1}) { "name" : "Bob" }
We've adjusted our query to contain query criteria that selects only cats that have a color of orange. Bob
is the only orange cat, so this is the only document returned. Again, we will suppress _id
and tell MongoDB that we only want to see the name field.
What if we want to change a record in our database? There are several methods to do this, but we'll start with the simplest one. MongoDB provides the appropriately named update method to modify documents in a database, as follows:
> db.cat.update({name:"Bob"},{$set:{color:"purple"}}) WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 }) > db.cat.find({color:"orange"},{_id:0,name:1}) > db.cat.find({color:"purple"},{_id:0,name:1}) { "name" : "Bob" }
Similar to the find method, the first argument to the update method tells MongoDB which documents to select. By default, however, MongoDB will only update one document at a time. To update multiple documents, we will add a third argument, a modifier object, {multi:true}
.
We have selected documents where the name field equals Bob
(there is only one). Then, we will use the $set
operator to change color of Bob
to purple.
We can verify that this has worked by querying for orange
cats using the following command:
> db.cat.find({color:"orange"},{_id:0,name:1}) > db.cat.find({color:"purple"},{_id:0,name:1}) { "name" : "Bob" }
No documents are returned. A query for purple cat
now returns our document for a cat
named Bob
.
No set of CRUD operations is complete without the D or Delete operation. MongoDB provides the remove method for this, which is as follows:
> db.cat.remove({color:"purple"}) WriteResult({ "nRemoved" : 1 }) > db.cat.find({},{_id:0,name:1}) { "name" : "Tom" }
The remove method has a fairly similar signature to the other MongoDB CRUD methods. The first argument, as you may have surmised, is a selector to choose which documents MongoDB should be removed.
In the preceding example, we removed all documents containing the purple
value for the color property. There was only one, so goodbye poor Bob
. We verified with our call to the find method which now only returns Tom
.
The default for the remove method is to delete all found documents, so use caution. Passing an empty selector will delete all documents in a collection, as follows:
> db.cat.remove({}) WriteResult({ "nRemoved" : 1 }) > db.cat.find() >
And with that, we have no cats.
MongoDB has no built-in rollback functionality, so there's no real way to undo such a deletion. In production, this is one reason why replication and regular database backups are important.
So, now that we have mucked about with MongoDB a little bit, let's create the development database we will use for the SPA we are building.
In a later chapter, we will use a Node.js plugin called mongoose to model to validate, query, and manipulate our data.
For now, let's just get the database set up. In your mongo shell, type the following command:
> use giftapp switched to db giftapp
Remember, we haven't actually created the database yet. For that, we will need to stick a document into a collection. As we'll let Mongoose do all of the heavy lifting for us later, we'll just put something in a test collection to get started. Let's consider the following code as an example:
> db.test.insert({test:"here is the first document in the new database"}) WriteResult({ "nInserted" : 1 }) > db.test.find() { "_id" : ObjectId("565ce0a2d9d61e2dc6141821"), "test" : "here is the first document in the new database" } > show dbs giftapp 0.078GB local 0.078GB test 0.078GB
Here, we will insert a document into the test collection. We can verify it's there with a call to the find method. Finally, we will run showdbs
and see that our giftapp
database is successfully created.
18.226.34.25