Mongoose read operations can be done using the ‘Model.find’ function, as shown below. ‘Model.find’ is also a Mongoose find operation. 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(comments)‘ statement 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) { //This is the callback for the mongoose read operation 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.
- Type ‘mongo’ at the command prompt (Windows) or console (Linux/Unix).
- Type ‘use test’ to switch to the database named ‘test’.
- 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.