Open In App

Understanding Mongoose Middleware in Node.js

Last Updated : 10 May, 2024
Improve
Improve
Like Article
Like
Save
Share
Report

A Mongoose is a powerful tool for NodeJS developers working with MongoDB databases. It simplifies database interaction, allowing developers to focus more on building their applications. In this article, we’ll cover the basics of Mongoose, including how to connect to a MongoDB database and perform CRUD operations. We’ll also explore Mongoose middleware, which lets developers add custom code before or after database operations, and share some best practices for using Mongoose efficiently.

What is Mongoose?

Mongoose is like a bridge between MongoDB and NodeJS, helping them work together smoothly. It’s designed to handle JavaScript code that runs asynchronously, meaning it can handle tasks that happen at different times. With Mongoose, you can create a blueprint, or schema, for how your data should look in your application. This not only ensures that your data follows a certain structure but also helps with validating the data you store.

How to get Start with Mongoose?

To get started with Mongoose, you first need to install it in your Node.js project using npm or yarn:

npm install mongoose    

or

yarn add mongoose

Once installed, you can connect to your MongoDB database using Mongoose’s connect() method:

JavaScript
// express --> index.js
// connect to mongodb using mongoose.connect

const mongoose = require('mongoose');

mongoose.connect('mongodb://localhost/my_database')
  .then(() => console.log('Connected to MongoDB'))
  .catch(error => console.error('Connection error:', error));

With the database connected, you can define Mongoose schemas to represent your data models and create corresponding models using these schemas. Here’s an example of defining a simple user schema and creating a user model:

JavaScript
// index.js

const userSchema = new mongoose.Schema({
  username: String,
  email: String,
  age: Number
});

const User = mongoose.model('User', userSchema);

Performing Basic Operations with Mongoose

Once you have defined your models, you can perform basic CRUD (Create, Read, Update, Delete) operations using Mongoose methods:

Create: To create a new document in the database, you can use the create() method:

//Pseudo code for create

const newUser = await User.create({ username: 'gfg', email: 'gfg@example.com', age: 30 });

Read: To retrieve documents from the database, you can use methods like find() or findOne():

//Pseudo code for Read

const users = await User.find({ age: { $gte: 25 } });

Update: To update existing documents, you can use methods like updateOne() or findByIdAndUpdate():

//Pseudo code for update

await User.updateOne({ username: 'gfg' }, { age: 35 });

Delete: To delete documents from the database, you can use methods like deleteOne() or findByIdAndDelete():

//Pseudo code for deletion

await User.deleteOne({ username: 'gfg' });

Middleware in Mongoose

Middleware in Mongoose allows you to define functions that execute before or after certain operations on the database. There are two types of middleware hooks: pre and post. Additionally, there are four specific types of middleware: document middleware, model middleware, aggregate middleware, and query middleware

Pre Middleware hook

Pre middleware functions are executed before the specified operation (e.g., save, update, remove). You can use pre middleware to perform actions like validation, encryption, or logging before saving, updating, or removing documents from the database.

// Pseudo code

userSchema.pre('save', async function(next) {
// Pre-save logic here
next();
});

Post Middleware hook

Post middleware functions are executed after the specified operation. You can use post middleware to perform actions like logging or sending notifications after saving, updating, or removing documents from the database.

//Pseudo code

userSchema.post('save', function(doc, next) {
// Post-save logic here
next();
});

Document Middleware

Document middleware in Mongoose allows you to create functions that run before or after certain actions on individual documents. These actions could include things like checking data, changing it, or securing it.

//Pseudo code

userSchema.pre('validate', function(next) {
// Execute pre-validation logic for documents here
next();
});

userSchema.post('validate', function(doc, next) {
// Execute post-validation logic for documents here
next();
});

Model Middleware

Model middleware in Mongoose is designed for tasks that affect the entire collection, not just individual documents. It’s useful for actions that need to happen before or after making big changes to the data, like updating many items at once or deleting a bunch of records.

//Pseudo code

userSchema.pre('deleteMany', function(next) {
// Execute pre-deleteMany logic for the model here
next();
});

userSchema.post('deleteMany', function(result, next) {
// Execute post-deleteMany logic for the model here
next();
});

Aggregate Middleware

Aggregate middleware in Mongoose specializes in managing aggregation operations. It allows you to intercept and adjust the results of aggregation queries.

//Pseudo code

userSchema.pre('aggregate', function(next) {
// Execute pre-processing logic for aggregation here
next();
});

userSchema.post('aggregate', function(result, next) {
// Execute post-processing logic for aggregation here
next();
});

Query Middleware

Query middleware in Mongoose helps intercept and modify queries before or after they are executed. This allows you to add extra conditions, modify the results, or perform other tasks related to the query process.

//Pseudo code

userSchema.pre('find', function(next) {
// Execute pre-find logic for queries here
next();
});

userSchema.post('find', function(result, next) {
// Execute post-find logic for queries here
next();
});

Best Practices for Using Mongoose Efficiently

  • Define indexes for frequently queried fields to improve query performance.
  • Use lean queries (lean()) for read-only operations to reduce memory usage.
  • Avoid nested schemas for better performance and simplicity.
  • Use schema validation to ensure data integrity and consistency.
  • Monitor and optimize database queries using Mongoose query hooks.

Conclusion

Mongoose serves as a powerful tool for MongoDB object modeling in NodeJS applications. By mastering its features, including basic operations, middleware, and best practices, developers can build robust and efficient applications that leverage the full potential of MongoDB. With Mongoose middleware, you can modularize your code, enhance data validation, and add custom logic to your database operations seamlessly. As you continue your journey with Mongoose, explore its capabilities, experiment with middleware, and refine your MongoDB workflows to create high-quality applications.




Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads