Pre and Post Middleware Hooks (Document & Query Middleware)0%
Pre and Post Middleware Hooks (Document & Query Middleware)
Beginner12 min read•Updated: Jul 11, 2026
Pre and Post Middleware Hooks (Document & Query Middleware)
Mongoose middleware (also referred to as Pre and Post Hooks) allows developers to execute logic automatically during the lifecycle of a document or query. Pre/Post hooks are essential for automated password hashing, slug generation, cascading deletes, and query filtering.
1. Document Middleware vs Query Middleware
- Document Middleware: Operates on the individual document instance (
thispoints to the document). Hooks:save,validate,remove,init. - Query Middleware: Operates on a Mongoose query object (
thispoints to the query). Hooks:find,findOne,findOneAndUpdate,countDocuments.
2. Document Middleware Example: Slug Generation & Password Hashing
JavaScript
import { Schema, model } from 'mongoose';
import slugify from 'slugify';
import bcrypt from 'bcrypt';
const userSchema = new Schema({
name: String,
email: String,
password: {
type: String,
required: true,
select: false // Exclude password from query results by default
},
slug: String
});
// PRE-SAVE HOOK: Automatically hash password if modified
userSchema.pre('save', async function(next) {
// Only run if password field was modified (or created)
if (!this.isModified('password')) return next();
// Hash password with cost factor of 12
this.password = await bcrypt.hash(this.password, 12);
next();
});
// PRE-SAVE HOOK: Automatically generate URL slug from name
userSchema.pre('save', function(next) {
if (this.isModified('name')) {
this.slug = slugify(this.name, { lower: true, strict: true });
}
next();
});
3. Query Middleware Example: Soft-Delete Auto-Filter
To implement "soft deletes" (hiding deleted records rather than permanently deleting them), use a pre(/^find/) regex hook to automatically filter out soft-deleted documents on all find queries:
JavaScript
// Automatically exclude soft-deleted documents from any find, findOne, etc.
courseSchema.pre(/^find/, function(next) {
// 'this' refers to the Query object
this.find({ isDeleted: { $ne: true } });
this.start = Date.now();
next();
});
// POST-FIND HOOK: Measure and log query duration
courseSchema.post(/^find/, function(docs, next) {
const elapsed = Date.now() - this.start;
console.log(`Query completed in ${elapsed}ms`);
next();
});
Interactive Quiz
Multiple Choice Questions
Question 1
In a Mongoose
pre('save') document middleware hook, what does this keyword refer to?Question 2
Why is checking
this.isModified('password') critical before hashing a password in a pre('save') hook?Question 3
What does regex middleware
schema.pre(/^find/, ...) match?Question 4
What parameters are passed to a
post('save') hook?Question 5
What must you call at the end of asynchronous middleware if you use the
next parameter callback style?Next Lesson
Virtual Properties, Instance Methods & Static Model Methods
Continue learning with hands-on practice, examples, and exercises in the upcoming topic.
Related Lessons
Practice Quiz
Test your understanding of this lesson with 5 questions. Each question has one correct answer.