« Previous Tutorial » Next Tutorial

Here we are again with another episode of Five Minute React. In our last tutorial, we got MongoDB installed and running. In this one, we’re going to take a few minutes to talk to it. This process is identical between Mac and PC other than whether you’re running terminal windows or command prompts (or Power Shell, which is just enough like a Unix shell to make you forget you’re not using a Unix shell until it doesn’t recognize a command and frustrates the hell out of you). The MongoDB daemon and the MongoDB console, which we’ll get to, behave exactly the same on both systems.

So! If you still have your MongoDB daemon running, awesome. If not, fire that sucker up and then open a new terminal window. As you can see, I’ve separated the two out so you can see both at the same time, because the MongoDB daemon does stuff when you’re connected either through the console or through a web app. Mostly what it’s doing is logging, and honestly when I’m actually developing, I basically never look at the daemon, but it can be interesting to see what’s going on over there when you’re getting started.

In your new terminal window, the one not running mongod, just type mongo. No D on the end, no config stuff, just the word mongo. This will launch the MongoDB console, which allows you to interact with the database (which is being run by the daemon). You’ll get a few basic pieces of information – including a warning about this database being accessible without access control, ie: a username and password authentication system being enabled. Never fear, mongo console, we will absolutely enable access control before we start producing code intended for live servers. For right now, we’re just messing around.

You’re left with an input prompt, so let’s input something. We’ll start with the following command:

show dbs

This is going to reveal two extremely empty databases: admin and local. You can ignore them; we’re not going to work in either. We’re instead going to create our own database in which to work. This next step is really important, because if you don’t follow the commands exactly, you’ll end up jamming data into the wrong place, and then it’ll be a pain to retrieve it. So, to start, type this:

use musiclist

You’ll see the console report that it’s switched to using a new db called musiclist – but if you repeat the show dbs command, you won’t see musiclist in the resulting output. This is because Mongo doesn’t actually create the database until you put some data into it.

MongoDB allows you to divide your database into sub-groups called Collections. For example, in a blog app, you might have a Users collection, and a Posts collection, and perhaps a Comments collection. We’re going to quickly add some data here, although we’re going to blank it before we actually get started on developing MusicList, which is the app we’ll be creating throughout these Five Minute React tutorials. Here, let’s add a user. Type the following:

db.users.insert({ fullName: 'John Smith', email: 'johnsmith@testemail.com' });

You’ll get the following response:

WriteResult({ "nInserted" : 1 })

That’s a little obtuse, but what it’s saying is “we inserted your user into the users collection.” Since this is the first time we’ve done this, it also created the users collection automatically, and since this is the first time we’ve done any work at all on the musiclist DB, it also created that. Pretty handy, huh? Type:

show dbs

again and you’ll see that musiclist is now there. If you type just

db

it’ll show that we’re actively working in the musiclist db at the moment. And if you type

show collections

it’ll show our brand new user collection. This is handy if you need to prepopulate data, or if you want to do some manual editing outside of your API, which I never recommend for production purposes, but is often necessary for development purposes, especially early on when you don’t actually have an API built yet.

You probably noticed that very JavaScript-like syntax that we used above to create our first user. That’s one of the really nice things about MongoDB: for JS developers, it feels very intuitive. Let’s take a look at the user we created by typing

db.users.find();

which will output:

{ "_id" : ObjectId("58d17a14f52141ed54476589"), "fullName" : "John Smith", "email" : "johnsmith@testemail.com" }

That’s nice enough, but with larger objects it might get a little cumbersome to have them printed like that. Fortunately, the Mongo console has a handy little method for dealing with that:

db.users.find().pretty();

which gets you this much nicer output:

{
        "_id" : ObjectId("58d17a14f52141ed54476589"),
        "fullName" : "John Smith",
        "email" : "johnsmith@testemail.com"
}

A big improvement! Note that MongoDB generated its own unique ID for our user. It’ll do this for any object you add to any collection. You can override the value manually if for some reason you think it’s a good idea, but I wouldn’t recommend it – you’ll be stepping on lots of functionality that proves really useful down the road. If you really want to add your own id for tracking purposes, consider a separate key/value pair like musiclistID: 12345 or similar.

Let’s add a few more users. We don’t have to do this with multiple db.users.insert() statements. We can stick multiple user objects into that one statement by putting them into an array. I like to start in a text editor and then paste into the console, so let’s open Sublime and enter the following:

db.users.insert([
  {
    fullName: 'Jane Doe',
    email: 'janedoe@testemail.com'
  },
  {
    fullName: 'Leslie Tanner',
    email: 'leslietanner@testemail.com'
  }
]);

Just paste that in to your mongo console, and you’ll get a response back:

BulkWriteResult({
        "writeErrors" : [ ],
        "writeConcernErrors" : [ ],
        "nInserted" : 2,
        "nUpserted" : 0,
        "nMatched" : 0,
        "nModified" : 0,
        "nRemoved" : 0,
        "upserted" : [ ]
})

… yeah. This not only tells you that we inserted two new records, but it also gives you a handy idea of what else you can do with this console, including modifying and removing an entry. Before we do anything else, though, let’s look at our complete three-user set by typing:

db.users.find().pretty();

And you'll get:

{
        "_id" : ObjectId("58d3c77d20ab241a7845c2fc"),
        "fullName" : "John Smith",
        "email" : "johnsmith@testemail.com"
}
{
        "_id" : ObjectId("58d3c78620ab241a7845c2fd"),
        "fullName" : "Jane Doe",
        "email" : "janedoe@testemail.com"
}
{
        "_id" : ObjectId("58d3c78620ab241a7845c2fe"),
        "fullName" : "Leslie Tanner",
        "email" : "leslietanner@testemail.com"
}

Looks great, huh? But what if we want to change something? Let’s do that, real quick. Let’s say that Jane modified her email:

db.users.updateOne(
  { fullName: 'Jane Doe' },
  { $set: { email : 'janeycakes@burnermail.com' } }
);

What that’s doing is saying “find a single entry whose fullName value is ‘Jane Doe’ and set her email to something new.” It’ll result in the following:

{ "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 }

Great! We matched one item and modified it. Now, I need to mention here that searching on strings like that is generally not a great idea. You could potentially have multiple users named Jane Doe, after all, and the updateOne method is only going to return the first one it finds. If you just used the update method, it’d change all of the returned users’ email addresses, which would also suck. The correct way to go, especially once we’re building our API, is to do lookups by unique IDs. But I can’t really do that here, because the IDs your system generates will not be the same as the ones mine generates. So, since this is a limited test, we’re just doing the lookup by name.

Let’s wrap this up by deleting a user. Alas, poor Leslie Tanner has decided that he or she no longer wishes to be a musiclist member, so it’s time to remove that entry from the database. Use the following code:

db.users.remove({ fullName: 'Leslie Tanner' });

That gets us another writeResult:

WriteResult({ "nRemoved" : 1 })

and sure enough, if we do another

db.users.find().pretty();

we’ll see that Leslie has moved to the great beyond, and we’ve only John and Jane left (and Jane has her new email address).

{
        "_id" : ObjectId("58d3c77d20ab241a7845c2fc"),
        "fullName" : "John Smith",
        "email" : "johnsmith@testemail.com"
}
{
        "_id" : ObjectId("58d3c78620ab241a7845c2fd"),
        "fullName" : "Jane Doe",
        "email" : "janeycakes@burnermail.com"
}

That’s about it for the basics of interacting with MongoDB. As you can see, everything is done through JavaScript-like commands, and results in BSON datasets that look pretty much like the JSON that most web folks have been working with for a while now. That’ll come in very handy when we start building our API which, believe it or not, is not so far away now!

We’re about to move from setup to coding. The next tutorial will prepare for this by establishing a source control repository with Git and Github. See you there.

« Previous Tutorial » Next Tutorial