MongoDB

NoSQL Databases

Introduction

MongoDB is one of the most popular NoSQL databases in use today. NoSQL stands for Not only Structured Query Language. NoSQL databases give us a different way to query data inside of their data stores, but it will be organized just the same. Let's get into some of the vocabulary that we'll use to discuss our data.


Collections

A collection is the top level container in our databases. We can have multiple collections inside each database, but each of these collections should maintain a specific type of data. For example, we might have a people collection, a books collection, a cars collection, etc. But each of those collections should only hold those types of objects. So let's take a look at what a basic users collection might look like:

[
  {
    "id": "12345",
    "name": "Lacey",
    "email": "lacey@wcci.org",
    "password": "password"
  },
  {
    // ...
  },
  {
    // ...
  }
]

Documents

The next step down is a Document. So a Collection represents a collection of Documents. So in our previous example, the document is:

{
  "id": "12345",
  "name": "Lacey",
  "email": "lacey@wcci.org",
  "password": "password"
}

So a document represents a single entry inside of the Collection.


Fields

Our last piece of vocab is Fields. Fields represent an individual piece of data inside of a document.

{
  "id": "12345",
  "name": "Lacey",
  "email": "lacey@wcci.org",
  "password": "password"
}

So for example, id is a field, name is a field, etc. So every individual piece that we can use is a Field in the Document.


MongoDB Atlas

There are a few different ways to create and access a MongoDB database. We can install it locally and run an instance of the database from our own machine or we can connect to a cloud based implementation. It is far more practical to be connecting to an outside database as that's what you ultimately have to do when you're creating applications that you actually deploy. So this is the approach that we will take.

We'll be using a service called MongoDB Atlas. Follow that link and create a new account.


Making Your First Cluster

Once you finish creating a new account you should be taken to a page with a pop up that prompts you to build your first Cluster. A cluster is essentially just a database instance. Click the big green button and let's keep going. On the second screen, click 'Developing a new app'.

  1. Now we should be on the 'Create New Cluster' page. Select 'aws' as the provider and 'N. Virginia' (because it has a free tier) and click Create Cluster at the bottom.
  2. Now, while we wait for the cluster to be created, we can create a user. This is how each person accessing the database will get access. Go to the Security tab and click 'Add New User' on the right. (all members of the team should have a unique user on the db). The username and password are different from your account username and password. These are ONLY to interact with this database.
  3. Next, Whitelist your machines IP so MongoDB Atlas will let you in when you connect from your application. Click the 'IP Whitelist' sub-tab in Security and then click 'Add IP Address' on the right. We're going to select 'Allow Access From Anywhere' for simplicities sake. In a real environment, you probably shouldn't do this.
  4. Connect to your cluster once it finishes creating by clicking the 'Connect' button in the Overview tab

Connecting to our App

If you don't have an application to connect your new db to, create on using the Express Generator:

  1. From ~/wcci/code: mkdir hello-mongo && cd $_
  2. Next: npm init -y
  3. Then we need to add mongodb as a dependency: npm i mongodb
  4. Finally: code .

Make a new file called index.js and let's add some stuff!


//index.js
const mongodb = require("mongodb");
const MongoClient = mongodb.MongoClient;

MongoClient.connect(
  "<url-for-your-db>",
  { useNewUrlParser: true },
  (error, client) => {
    const db = client.db("mongo-introduction");

    db.collection("people").insertOne(
      {
        name: "Brian",
        age: 37
      },
      (error, result) => {
        if (error) {
          return console.log("Unable to connect", error);
        }
        console.log(result);
      }
    );
  }
);

That's a lot of stuff... Let's go through it a little at a time


MongoClient

The first few things to go over all have to do with MongoClient. MongoClient is a property that we get from the MongoDB dependency that allows us to connect to outside clusters. The piece that we want to focus on is the connect() method from it. This method accepts 3 pieces.

  1. a location for your cluster in the form of a url string.
  2. a configuration object. All we need to include here is the useNewUrlParser: true entry, but there are more that you can add. I encourage you to take a look at the Mongo Docs for more on that.
  3. a callback function that will return either an error or a connection to the cluster. It is inside of this callback that we can actually interact with the cluster and more specifically a database.

Inside the Callback

The first thing we need to do once we're connected to the cluster is specify a database name that we want to work with. Our cluster can contain multiple actual databases.

const db = client.db("mongo-introduction");

This command will either identify an existing database that we want to interact with or create a new one if this one doesn't exist.


Inside the DB

Once we have a database to interact with, we can specify the collection that we will actually be working with.

db.collection("people");

This will specify the collection that we mean to perform CRUD (Create, Read, Update, Delete) operations on. From here we just need to choose one of a collection of methods to actually interact with the collection.


Create

Create One

We can add one Document to our collection like so:

db.collection("people").insertOne({ name: "Ben" }, (error, result) => {
  if (error) console.log("There was an error inserting the document!");
});

Create Many

And we can add multiple Documents to our collection like this:

db.collection("people").insertMany(
  [{ name: "Ben" }, { name: "Kendra" }],
  (error, result) => {
    if (error) console.log("There was an error inserting the document!");
  }
);

Read

Read One

Now we need to be able to get one Document

db.collection("people").findOne({ name: "Ben" });

This will return the first instance it finds that meets the given criteria.

Read Many

db.collection("people").findMany({ name: "Lacey" });

This will find all Documents where the name field is Lacey


Update

Update One

We can update an existing entity with new values.

db.collection("people").updateOne({ name: "Ben" }, { $set: { age: 30 } });

Update Many

We can update values in multiple Documents as well

db.collection("todos").updateMany(
  { complete: false },
  { $set: { complete: true } }
);

Delete

Delete One

We can delete one Document by specifying it (usually by id, but any field will work).

db.collections("heroes").deleteOne({ name: "Spiderman" });

Delete Many

We can also get rid of multiple entries at a time

db.collections("tasks").deleteMany({ complete: true });

Conclusion

Being able to interact with our database is a critical step to developing applications. It makes managing large collections of data so much easier and more secure. Make sure to check out the Mongo Docs as well.