Use Indexes Effectively
// In your schema
ExampleSchema.index({ user_id: 1, updated_at: -1 }) // Compound index for sorting
ExampleSchema.index({ user_id: 1, show_id: 1 }) // Compound index for grouping
// In your query
.hint({ user_id: 1 }) // Force using index
Project Only Needed Fields
{
$lookup: {
from: 'shows',
let: { show_id: '$_id' },
pipeline: [
{
$match: {
$expr: { $eq: ['$_id', '$$show_id'] }
}
},
{
$project: {
// Only get fields you need
title: 1,
coverImage: 1,
slug: 1
}
}
],
as: 'show'
}
}
Use $facet for Multiple Operations
{
$facet: {
// Get count in parallel with results
total: [
{ $group: { _id: '$show_id' } },
{ $count: 'count' }
],
result: [
// Your main query pipeline
]
}
}
Early Filtering
// Do this first
{
$match: { user_id: ObjectId(user_id) }
}
// Before expensive operations like
{ $sort: ... }
{ $group: ... }
Efficient Data Processing
// Instead of multiple $lookup stages
{
$project: {
show: {
$mergeObjects: [
{ $arrayElemAt: ['$show', 0] },
{ url: { $arrayElemAt: ['$episode.url', 0] } }
]
}
}
}
Use Aggregation Stages in Right Order
[
{ $match: ... }, // Filter first
{ $sort: ... }, // Sort early if possible
{ $group: ... }, // Reduce document count
{ $skip: ... }, // Pagination after reducing
{ $limit: ... }, // Limit results
{ $lookup: ... }, // Join with other collections
{ $project: ... } // Final shape
]
// Add explain() to see query plan
const explain = await Example.aggregate([...]).explain('executionStats')
console.log(explain.executionStats.executionTimeMillis)
const perPage = 6
const page = parseInt(req.query.page) || 1
const offset = (page - 1) * perPage
// In pipeline
{ $skip: offset }
{ $limit: perPage }
Error Handling and Defaults
try {
const result = await query
return {
total: total || 0, // Default if null
result: result || [] // Default if null
}
} catch (error) {
console.error('Query error:', error)
return rep.internalServerError()
}
// In MongoDB Compass or Shell
db.example.aggregate([...]).explain("executionStats")
// Check indexes
db.example.getIndexes()
// Check collection stats
db.example.stats()
- Always test with real data volumes
- Monitor query performance in production
- Use appropriate indexes for your query patterns
- Keep your queries as simple as possible
- Filter early, project late -> These principles will help you write efficient MongoDB queries!