Some mongoDB + mongoose + NodeJS basics
Tags: mongodb, learning
Published: 2019-03-01 21:36:28

---
title: Some mongoDB + mongoose + NodeJS basics
published: true
description: 
tags: mongodb, learning
---

### warnings

Note that this is strictly a hello-world kind of exercise. In a real environment, you'd probably have some more security configuration on your database. This creates an entirely unprotected database that can be read or modified by anyone who connects to it. With that said, here's a guide for how to go from a basic understanding of NodeJS to reading from / writing to a mongoDB database.

### getting MongoDB's process running

Here's a big-picture breakdown of MongoDB. MongoDB is made up of **databases**, which have **collections** inside of them, which contain multiple **documents**. In `mongoose`, the **documents** are essentially javascript objects that follow a pattern that follows a **schema** that we define.


In order to get anything done in our database, we need to have a process running that will allow users to access it. In order to do this, you want to install MongoDB, and then run `mongod`. You may have errors regarding permissions in /data/db. This is because /data/db is a protected folder, and you may need to run mongod as a superuser (which may not be the best- I'm not clear on the security implications here). it looks like this: `sudo mongod`. (Leave this window open so that the process can continue to run, and don't touch it unless you want to shut down your database.)

When you type `sudo mongod`, part of what shows up on your console should look like this: `MongoDB starting : pid=2265 port=27017 dbpath=/data/db`. The port for a mongoDB instance is 27017 by default, but it will always be printed when you start up mongod. just look for **port**. This will be important later.

Now, your database will be stored at /data/db, though not in any format that seems to be readable to us. We can access our databases through the mongo shell, which we'll get into later.


### Creating and configuring our NodeJS server
Now, we can finally get into creating and configuring our server. 

First, we have to `npm init` in our desired directory to create our server, then we'll `npm install mongodb` and `npm install mongoose` as a bare minimum for a proof of concept / hello world-type server.

We'll create a file called `server.js` in our project folder that we'll run using `node server.js`. This `server.js` will contain all of the logic that our server follows.

Our goal is to create a database, write to it, and read from it, all from our server. Here's a quick roadmap of how we'll do it:

1. import mongoose
2. connect to our database
3. create a **schema** object using mongoose.Schema() constructor and an object that defines the criteria (keys, datatype, etc) for our data
4. create a **model** by using mongoose.connect(), with the name of our **collection**, and the **schema** object we just created
5. use the **model** as a constructor function to generate a mongoDB **document** object
6. the mongoDB **document** object that we have returned will have a method called save(), which will allow us to save it to the database.
* If we want to find our data afterwards, our **model** (not the document), has a method called 'find()'. Note that our database methods are asynchronous.
  

### step 1: import mongoose inside of our server file.
```javascript
//in server.js
const mongoose = require('mongoose')

```

Next, let's connect to our database. Once again, if you've run `mongod` in your CLI, it should print out some information, including a port number (27017 by default). If you're connecting to a remote host, they'll provide the information required to log in.

### step 2: connect to db

You'll connect at `mongodb://localhost:<portnumber>/<databasename>`, and it'll look like this:

```javascript
//in server.js
const mongoose = require('mongoose')
mongoose.connect('mongodb://localhost:27017/test', {useNewUrlParser: true});

```

You may have noticed that we've added 'test' to the end of `mongodb://localhost:27017/test`. `test` is the name that we're choosing to call our database. We haven't created this database yet, but it doesn't matter, because in MongoDB, it will be created when we start storing documents on it.

Now that this connection has been established, we can start creating schemas, models, and documents. This starts with our `mongoose.schema` method, which is a constructor function that lives on `mongoose`

Let's store our `mongoose.schema` on a const, so we can access it more easily.

### step 2.5: save our schema method
```javascript
//in server.js
const mongoose = require('mongoose')
mongoose.connect('mongodb://localhost:27017/test', {useNewUrlParser: true});
const Schema = mongoose.Schema
```

mongoose.Schema is a constructor that takes an object.

The object that we give to the constructor is a 'schema' that represents the structure of our data, with key/value pairs. 

### Step 3: create a schema

 In our example code, our schema will be called exampleSchema.

```javascript
//in server.js
const mongoose = require('mongoose')
mongoose.connect('mongodb://localhost:27017/test', {useNewUrlParser: true});
const Schema = mongoose.Schema
const exampleSchema = new Schema({
    someKeyName: {type: String, required: true, unique:true},
    someOtherKeyName: {type: Number, required: false, unique:false}
})
```
What this means is that each object in our collection is going to have two keys: someKeyName and someOtherKeyName. The value stored on someKeyName will have a type of `String`, will be required, and will be unique. The value stored on someOtherKeyName will need to be a `Number`, and is neither required nor unique (I'm not sure what unique is).

### Step 4: Create a Model

Next, we'll create something called a 'model', which will link our schema to our collection.

we invoke `mongoose.model()`, which takes two arguments, one of which is a string that is the name of our collection, the other of which is the new object we created. Once again, it doesn't matter that we haven't already created a collection. MongoDB will create it for us once we try to store data inside of it.



```javascript
//in server.js
const mongoose = require('mongoose')
mongoose.connect('mongodb://localhost:27017/test', {useNewUrlParser: true});
const Schema = mongoose.Schema
const exampleSchema = new Schema({
    someKeyName: {type: String, required: true, unique: true} ,
    someOtherKeyName: {type: Number, required: false, unique:false}
})
const newModel = mongoose.model('collectionName', exampleSchema)
```

that step links the schema with a name for your collection (which produces a 'model'). This model is actually a constructor function, which creates 'document' objects.

### step 5: Create a document

In order to do this, we take our model (`newModel`), and give it an object that holds all of the data that we want to go in a single document.

```javascript
//in server.js
const mongoose = require('mongoose')
mongoose.connect('mongodb://localhost:27017/test', {useNewUrlParser: true});
const Schema = mongoose.Schema
const exampleSchema = new Schema({
    someKeyName: {type: String, required: true, unique: true} ,
    someOtherKeyName: {type: Number, required: false, unique:false}
})
const newModel = mongoose.model('collectionName', exampleSchema)
const newDocument = newModel({someKeyName: 'hi', someOtherKeyName: 12345})
```


### step 6: save the document

Now the `newDocument` object exists, we have access to methods on it. One of these is a `save` method. It does exactly what you think it does.

```javascript
//in server.js
const mongoose = require('mongoose')
mongoose.connect('mongodb://localhost:27017/test', {useNewUrlParser: true});
const Schema = mongoose.Schema
const exampleSchema = new Schema({
    someKeyName: {type: String, required: true, unique: true} ,
    someOtherKeyName: {type: Number, required: false, unique:false}
})
const newModel = mongoose.model('collectionName', exampleSchema)
const newDocument = newModel({someKeyName: 'hi', someOtherKeyName: 12345})
newDocument.save()
```

Congrats! you just used mongoose to create and write to a database.

Let's go ahead and verify that the document exists in our collection. You can do this outside of node through the next sequence of commands:

`mongo` will spin up the mongo command line.

inside of the mongo command line interface, you can type the following:

`show dbs` will show you a list of dbs. You should see `test` on the list.  
`use test` will log you into your `test` database.  
`show collections` will show you the collections in your `test` database. You should see a `collectionName` collection printed out.  
`db.collectionName.find()` will do an empty query on the `collectionName` database, which should return every document within that collection.  
you should see something like this: `{ "_id" : ObjectId("5c78204590796a1c74a20b11"), "someKeyName" : "hi", "someOtherKeyName" : 1234, "__v" : 0 }`  

There's your database entry!

Of course, this is not so useful for us. Given that we're trying to work with our database from inside of nodeJS, we need to be able to read from our database within our server file. 

Back inside of the server, let's invoke a 'find' on our model in order to read from the database.

```javascript
//in server.js
const mongoose = require('mongoose')
mongoose.connect('mongodb://localhost:27017/test', {useNewUrlParser: true});
const Schema = mongoose.Schema
const exampleSchema = new Schema({
    someKeyName: {type: String, required: true, unique: true} ,
    someOtherKeyName: {type: Boolean, required: false, unique:false}
})
const newModel = mongoose.model('collectionName', exampleSchema)
newModel.find({somekeyname:'hi'}, (err,results)=>{
    console.log(results)
})
```

This may require a bit of explanation. The first argument is fairly clear. it's an object with key/value pairs that we're searching for. The second argument (called a callback function) may be a little less obvious.

Basically, we expect `newModel.find` to query our database, then do something with the data. What does it do? That's defined in our callback function. If the search fails for some reason, it'll pass in an argument as `err`, and if it succeeds, we'll get something in `results`.

`{someKeyName: "hi"}` should match our entry `{ "_id" : ObjectId("5c78204590796a1c74a20b11"), "someKeyName" : "hi", "someOtherKeyName" : 1234, "__v" : 0 }`, and we don't have anything else in our database, so our `results` variable will evaluate to this: `[{ "_id" : ObjectId("5c78204590796a1c74a20b11"), "someKeyName" : "hi", "someOtherKeyName" : 1234, "__v" : 0 }]`. `console.log` will simply print that value to our terminal.

Note that, even though it's just one item, the callback for `find` returns an array. If it doesn't find anything, it'll just give an empty array `[]`. 

Now that you've got the array of matches, you can start to do stuff with it, whether that's looking up and displaying information, checking authentication, or other such operations!