DEV Community

tang
tang

Posted on • Updated on

Some mongoDB + mongoose + NodeJS basics

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.
  7. 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.

//in server.js
const mongoose = require('mongoose')

Enter fullscreen mode Exit fullscreen mode

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:

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

Enter fullscreen mode Exit fullscreen mode

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

//in server.js
const mongoose = require('mongoose')
mongoose.connect('mongodb://localhost:27017/test', {useNewUrlParser: true});
const Schema = mongoose.Schema
Enter fullscreen mode Exit fullscreen mode

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.

//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}
})
Enter fullscreen mode Exit fullscreen mode

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.

//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)
Enter fullscreen mode Exit fullscreen mode

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.

//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})
Enter fullscreen mode Exit fullscreen mode

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.

//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()
Enter fullscreen mode Exit fullscreen mode

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.

//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)
})
Enter fullscreen mode Exit fullscreen mode

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!

Top comments (0)