Mongoose Basics: Storing Data With Node.js And MongoDB

Posted By: Nicholas Brown.

When I first started learning how to use the Mongoose library, I encountered some problems which were not addressed in many of the MongoDB CRUD tutorials I read (you can learn more about CRUD operations here). Most of them start with a very simple introduction to Mongoose, in which everything is plopped in the same file, as shown below.

The sample code connects to a MongoDB database server (a ‘mongod’ instance) and writes it to a database named ‘test’. Before trying any of the code below, install the MongooseJS library by typing npm install mongoose in the root of the directory containing your .js files.

Mongoose code example
Code sample showing how to save data with MongoDB (using the Mongoose library).
1. var mongoose = require("mongoose");
2. mongoose.connect("mongodb://localhost:27017/test");
3. 
4. var db = mongoose.connection;
5. 
6. db.on("error", console.error.bind(console, "connection error"));
7. db.once("open", function(callback) {
8.     console.log("Connection succeeded.");
9. });
10. 
11. var Schema = mongoose.Schema;
12. 
13. var bugSchema = new Schema({
14.     bugName: String,
15.     bugColour: String,
16.     Genus: String
17. });
18. 
19. var Bug = mongoose.model("Bug", bugSchema);
20. 
21. var Bee = new Bug({
22.     bugName: "Scruffy",
23.     bugColour: "Orange",
24.     Genus: "Bombus"
25. });
26. 
27. Bee.save(function(error) {
28.     console.log("Your bee has been saved!");
29. if (error) {
30.     console.error(error);
31.  }
32. });

While this is a great starting point (due to it’s simplicity) for learning to store data with MongoDB, it helps to go a little further and explain how to organize this program better once the user has grasped the basics. It comes in handy later when your programs become more complex (especially if you have many models and schemas). Chances are, you’ll want to store quite a few different types of data in your MongoDB database (or databases).

I split the project into three files (these are called modules in Node.js): index.js, models.js, and Bugs.js (in the Models directory), as shown below. The objects created from our modules (Models.js and Bugs.js) are highlighted in this shade of red throughout this article. The .js files shown below are modules (thanks to Philipp Holly from dvel for pointing me in the right direction).


File: index.js 

1. var Models = require("./models"); //Instantiate a Models object so you can access the models.js module.
2.
3. var Bee = new Models.Bug({ //You're entering a new bug here, giving it a name, and specifying it's type.
4.    bugName: "Scruffy",
5.    bugColour: "Orange",
6.    Genus: "Bombus"
7. });
8. 
9. Bee.save(function(error) { //This saves the information you see within that Bee declaration (lines 4-6).
10.    console.log("Your bee has been saved.");
11. if (error) {
12.    console.error(error);
13.   }
14. });

The ‘Bug’ in Models.Bug (line 4) is a model I created in the Node module models.js, as you can see in the following code snippet. The Bugs schema (bugSchema) was defined in its own file — Bugs.js, and imported into models.js using the require statement on line 2. Bug, on the other hand is the model you’ll use in the index.js file.

In models.js, the Bug model is created using bugSchema and exported. The module.exports statement enables you to export whichever object is at the end of that final period (line 14 of models.js).

In this case, that object is the Bug Model. ‘module.exports.Bug’ simply allows other modules (like models.js, or any other Node.js file in its path) to use/import it.

The ‘= Bug’ is the name of the object to export, which is a model in this case. If you wanted to be able to type ‘Models.Insect’ instead of ‘Models.Bug’ on line 3 of index.js, you would change line 14 of models.js from ‘module.exports.Bug = Bug;’ to ‘module.exports.Insect = Bug;’.

NB: For those that don’t already know, a schema is a plan or representation outlining how something is structured, or how it works. It can also be called a ‘scheme’. Schemas are defined using a language (in this case, it is JSON, which is JavaScript Object Notation). Consider it a plan defining how data is organized.

The database schemas shown below simply define the fields that this program will store in your MongoDB database, as well as the data type of the fields (denoted by the String, Number, and Boolean declaration after the colon’). There are other data types, but I was just naming a few.

It’s the code on line 9 of index.js that saves your data as a document to the bugs collection in your MongoDB database. A collection is a group of documents that contain your data. Mongoose automatically names collections based on the model name in quotes on line 12 of models.js.

It converts the name to lowercase and appends an ‘s’. This means that if you named your model ‘Kitten’, Mongoose would create a collection named ‘kittens’ to store it in. MongoDB receives data and queries in JSON format, and it also returns data in JSON format.

Note: I used multi-line comments (denoted by a /* and */) to compensate for word wrapping on smaller screens. This helps to reduce the likelihood of confusion.

File: models.js

1. var mongoose = require("mongoose");
2. var Bugs = require("./Models/Bugs"); /* Imports the Bugs module. It contains the bug schema we need. */
3. mongoose.connect("mongodb://localhost:27017/test"); //Test is the database name. 
4. 
5. var db = mongoose.connection;
6. 
7. db.on("error", console.error.bind(console, "Connection error:"));
8. db.once("open", function(callback){
9.     console.log("Connection Succeeded."); /* Once the database connection has succeeded, the code in db.once is executed. */
10. });
11. 
12. var Bug = mongoose.model("Bug", Bugs.bugSchema); //This creates the Bug model.
13. 
14. module.exports.Bug = Bug; /* Export the Bug model so index.js can access it. */

Translated to English, line 3 instructs the server to do the following: Connect to the mongod instance running on localhost using port 27017, and use the database named ‘test’. mongod is the MongoDB database server, it is a process called a daemon. It receives database queries and performs create, read, update, and delete operations on data in the DB.

Note that the database connection is performed only in models.js. I did that to avoid creating unnecessary duplicate connections. The connect statement is only needed in models.js in this case, anyway. This enables you to avoid commonly-encountered Mongoose connection errors, including ‘Error: Trying to open unclosed connection.’, and ‘{ [Error: Trying to open unclosed connection.] state: 2 }’ (discussed with other possible solutions here).

This connection method is intended for apps that will use one connection to the database server. However, there are ways to create multiple connections, including the createConnection method.

File: Models/Bugs.js

1. var mongoose = require("mongoose");
2. var Schema = mongoose.Schema;
3. 
4. var bugSchema = new Schema({ //This is where bugSchema is defined.
5.     bugName: String,
6.     bugColour: String,
7.     Genus: String
8. });
9. 
10. module.exports.bugSchema = bugSchema; //Export bugSchema so that models.js can access it.

Finally, you can navigate to that directory using the cd command (whether you’re in Windows, Linux, or a freeBSD variant). Type nodejs index.js to run your program, and finally start saving data with mongoose! The program above performs a create operation, because it is creating a new document in your collection.

A quick way to confirm your code works is to use the Mongo client to find it via the following procedure.

  1. Type ‘mongo’ at the command prompt (in Windows) or console (in Linux/Unix).
  2. Type ‘use test’.
  3. Then type the following to find Scruffy.
~$ db.bugs.find( { bugName: "Scruffy" } );

Further Reading

To learn how to install MongoDB and get started with the CLI, read my getting started guide.

Receive POST request data with Node.js. Once you learn this, you can communicate data between your website/mobile app and your MongoDB + Node.js back end easily. Once you learn how to do that, you can learn how to send a POST request (or GET request) with data from your Android app.

Looking for a Node.js developer? Send me an e-mail. I do highly-responsive full-stack development using Node.js, Express, Mongoose, HTML, CSS, and JavaScript.

How To Send GET Requests From A Node.js App and Save The Response In A Database.

Find Location Data For Businesses Nearby Using The Google Places API

Common Errors That Can Be Resolved With This Method

  • ‘Error: Trying to open unclosed connection.’
  • ‘{ [Error: Trying to open unclosed connection.] state: 2 }’

Common Mongoose Errors

If you encounter any errors when attempting this exercise, please let me know in the comment section. I will try to recreate the problem, post the error here, and possible solutions.


Code Successfully Tested With Node.js Version:

  • 4.2.6.
  • 4.3.1.
  • 6.9.5.

Code Successfully Tested With MongooseJS Version:

  • 4.4.2.
  • 4.4.6.
  • 4.10.4.

Facebook Comments

comments