Empowering you to understand your world

Introduction To Mongoose: Database Read Operations In Node.js

By Nicholas BrownFollow me on X.

Mongoose has a very simple Model.find function for MongoDB queries in Node.js, as shown below. In this case the model is Comment, as defined using the var statement near the end. ‘UserName’ in the Comment.find statement is just the field you’re searching by. So {UserName: ‘Nick’} is just instructing it to search for comments made under the username ‘Nick’.

The query results returned by MongoDB are saved in the comments variable, which you can name anything you wish. The console.log statement in purple is inside an asynchronous callback function, meaning that it will be executed only when the query is complete. This way, you can have slow database queries running in the background without them holding up all other tasks in your Node.js app until the queries are complete.

Placing that same console.log statement outside of the callback function’s braces (as done in red below) would cause it to execute before the query is finished, which would prevent you from displaying the comments. It would also fail to execute with a ‘comments is not defined’ error because the comments variable is defined inside the asynchronous ‘Comment.find()’ code block we defined. This pitfall would be harder to spot if ‘comments’ was a global variable.

The comments can only be displayed after Mongoose gets them from the database and assigns them to the comments variable. This asynchronous method is also called non-blocking I/O, a powerful feature offered by Mongoose and Node.js.

const mongoose = require('mongoose');

mongoose.connect('mongodb://localhost:27017/test'); //Connect to your running mongod instance using the database named 'test'.
//For now use this instead: mongoose.connect('mongodb://localhost:27017/test', {useNewUrlParser: true});
/*
You can change 'localhost' to the domain of the server mongod is running on. This is only necessary if your Node.js app is connecting to it remotely.

You can authenticate after creating a user account in MongoDB (and requiring authentication, otherwise user accounts would't protect your data) by
typing this instead:

mongoose.connect('mongodb://username:password@localhost:27017/test');
*/

const db = mongoose.connection;

db.on('error', console.error.bind(console, 'Connection error: '));
db.once('open', function(callback) {
//The code in this asynchronous callback block is executed after connecting to MongoDB.
    console.log('Successfully connected to MongoDB.');
});

const Schema = mongoose.Schema;

const commentSchema = new Schema({
    CommentBody: String,
    UserName: String,
    DatePosted: Date,
});

const Comment = mongoose.model('Comment', commentSchema);

Comment.find({UserName: 'Nick'}).then(function(comments, error) {
    if (error) {
        console.log(error);
    } else {
        console.log(comments); //Display the comments returned by MongoDB, if any were found. Executes after the query is complete.
    }
});
console.log(comments); //Wrong! Delete this line, as it will execute before the query is complete, resulting in an 'undefined' message.

If you have the Mongo client installed, you can quickly insert a test comment in the database using the following method, assuming that authentication is not enabled.

  1. Type ‘mongo’ at the command prompt (Windows) or console (Linux/Unix).
  2. Type ‘use test’ to switch to the database named ‘test’.
  3. Type the following:

db.comments.insert( { CommentBody: ‘This is a test comment.‘, UserName: ‘Nick‘, DatePosted: Date() } );

Troubleshooting

‘MongooseError: Model.find() no longer accepts a callback’

This error will occur if you code the ‘Comment.find()’ function the old way (which is now deprecated), as follows:

Comment.find({UserName: 'Nick'}, function(error, comments) {
   console.log(comments);
});

Code tested with Node.js version:

  • 20.2.0.

Code tested with Mongoose version:

  • 9.6.6.
Subscribe to our newsletter
Get notified when new content is published