Mongoose
Mongoose
Mongoose is a MongoDB Object Data Modeling (ODM) library for Node.js. It provides a powerful
framework to model your data, define schemas, perform CRUD operations, manage relationships
between different models, and add validation, middleware, and more. In this in-depth explanation, we
will dive into key concepts, features, and advanced topics in Mongoose.
1. Mongoose Basics
// Connect to MongoDB
A schema defines the structure of the documents within a MongoDB collection. It outlines the fields and
their types, validation, default values, and more.
// Define a schema
name: {
type: String,
required: true,
},
email: {
type: String,
required: true,
unique: true,
},
age: {
type: Number,
},
createdAt: {
type: Date,
default: Date.now,
},
});
module.exports = User;
A model is a constructor function that allows us to create and interact with documents that follow the
schema.
After defining the model, you can perform operations like creating, reading, updating, and deleting
(CRUD) documents in the associated MongoDB collection.
name: 'Alice',
email: '[email protected]',
age: 30,
});
newUser.save()
User.create({
name: 'Bob',
email: '[email protected]',
age: 25,
})
User.find()
User.findById('60c7f8f5b5f0d44b88abec30')
You can update documents using methods like update(), updateOne(), findByIdAndUpdate(), etc.
// Delete a user by ID
User.findByIdAndDelete('60c7f8f5b5f0d44b88abec30')
Mongoose provides built-in methods to handle complex queries such as pagination, sorting, and
filtering.
User.find()
if (err) {
console.log(err);
} else {
});
4.2 Filtering
You can use query operators such as $gt, $lt, $in, $ne, etc., to filter results.
5. Mongoose Middleware
Middleware in Mongoose can run before or after certain actions, such as saving, updating, or removing
documents. This can be useful for data validation, logging, or modifying data before it is saved.
• Pre Middleware: Runs before the action is performed (e.g., before saving a document).
• Post Middleware: Runs after the action is performed (e.g., after a document is saved).
if (this.isModified('password')) {
next();
});
// Post-save middleware
next();
});
if (!this.email.includes('@')) {
next();
});
6. Mongoose Virtuals
A virtual is a field that is not stored in the database but is derived from other fields. It's often used for
computed properties.
userSchema.virtual('fullName').get(function () {
});
This will add a fullName property to the document without saving it to the database.
7. Mongoose Population
Population is the process of replacing fields that store ObjectIds with the actual documents that are
referenced.
Imagine you have a Post model that has a reference to the User model for the author.
content: String,
author: {
type: mongoose.Schema.Types.ObjectId,
},
});
Post.find()
.populate('author') // Populate the author field with the actual user data
if (err) console.log(err);
else console.log(posts);
});
8. Mongoose Indexing
Indexing can improve the performance of queries that are frequently used, especially for large datasets.
You can also define compound indexes and set options like uniqueness.
Mongoose supports the MongoDB aggregation framework, which allows you to perform complex
queries, including grouping, sorting, and transforming data.
User.aggregate([
{ $match: { age: { $gte: 18 } } },
])
9.2 Transactions
session.startTransaction();
try {
await session.commitTransaction();
} catch (error) {
await session.abortTransaction();
} finally {
session.endSession();
10. Conclusion
Mongoose is a powerful tool that simplifies interacting with MongoDB from a Node.js environment. It
provides a rich set of features such as schema-based modeling, middleware, population, validation, and
aggregation, making it easier to manage and manipulate data. Understanding how to use Mongoose
effectively will help you build robust applications with MongoDB.