Pre and Post Middleware Hooks (Document & Query Middleware)0%

Pre and Post Middleware Hooks (Document & Query Middleware)

Beginner12 min read•Updated: Jul 11, 2026
Study MaterialsCheatsheet

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 (this points to the document). Hooks: save, validate, remove, init.
  • Query Middleware: Operates on a Mongoose query object (this points 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.

Practice Quiz

Test your understanding of this lesson with 5 questions. Each question has one correct answer.

PrevNext