Mongoose provides a powerful query builder that supports chainable calls and rich query operations, making MongoDB queries more intuitive and easy to use.
Basic Queries
Find All Documents
javascriptconst users = await User.find();
Conditional Queries
javascript// Equal const users = await User.find({ age: 25 }); // Not equal const users = await User.find({ age: { $ne: 25 } }); // Greater than const users = await User.find({ age: { $gt: 18 } }); // Greater than or equal const users = await User.find({ age: { $gte: 18 } }); // Less than const users = await User.find({ age: { $lt: 30 } }); // Less than or equal const users = await User.find({ age: { $lte: 30 } }); // In array const users = await User.find({ status: { $in: ['active', 'pending'] } }); // Not in array const users = await User.find({ status: { $nin: ['deleted'] } });
Logical Operators
javascript// AND const users = await User.find({ age: { $gte: 18 }, status: 'active' }); // OR const users = await User.find({ $or: [ { status: 'active' }, { status: 'pending' } ] }); // NOT const users = await User.find({ status: { $not: { $eq: 'deleted' } } }); // NOR const users = await User.find({ $nor: [ { status: 'deleted' }, { status: 'inactive' } ] });
Chainable Queries
Select Fields
javascript// Select specific fields only const users = await User.find() .select('name email age'); // Exclude specific fields const users = await User.find() .select('-password -__v'); // Use object syntax const users = await User.find() .select({ name: 1, email: 1, age: 1 });
Sorting
javascript// Ascending const users = await User.find() .sort({ name: 1 }); // Descending const users = await User.find() .sort({ age: -1 }); // Multi-field sort const users = await User.find() .sort({ status: 1, age: -1 });
Limit and Skip
javascript// Limit result count const users = await User.find() .limit(10); // Skip specified count const users = await User.find() .skip(5); // Pagination const page = 2; const pageSize = 10; const users = await User.find() .skip((page - 1) * pageSize) .limit(pageSize);
Advanced Queries
Regular Expressions
javascript// Contains const users = await User.find({ name: /john/i }); // Starts with const users = await User.find({ name: /^john/i }); // Ends with const users = await User.find({ name: /doe$/i });
Array Queries
javascript// Array contains specific value const users = await User.find({ tags: 'javascript' }); // Array contains multiple values (AND) const users = await User.find({ tags: { $all: ['javascript', 'nodejs'] } }); // Array size const users = await User.find({ tags: { $size: 3 } });
Nested Document Queries
javascript// Nested field query const users = await User.find({ 'address.city': 'New York' }); // Nested array query const users = await User.find({ 'orders.status': 'completed' });
Element Queries
javascript// Field exists const users = await User.find({ email: { $exists: true } }); // Field type const users = await User.find({ age: { $type: 'number' } });
Aggregation Queries
javascript// Group statistics const result = await User.aggregate([ { $match: { age: { $gte: 18 } } }, { $group: { _id: '$status', count: { $sum: 1 } } } ]); // Find and modify const user = await User.findOneAndUpdate( { email: 'john@example.com' }, { age: 25 }, { new: true } );
Query Optimization
Use Indexes
javascriptconst userSchema = new Schema({ email: { type: String, index: true }, age: { type: Number, index: true } }); // Compound index userSchema.index({ email: 1, age: -1 });
Projection Optimization
javascript// Only query needed fields const users = await User.find() .select('name email');
Use lean()
javascript// Return plain JavaScript objects, better performance const users = await User.find().lean();
Batch Operations
javascript// Batch insert const users = await User.insertMany([ { name: 'John', email: 'john@example.com' }, { name: 'Jane', email: 'jane@example.com' } ]); // Batch update const result = await User.updateMany( { status: 'pending' }, { status: 'active' } );
Query Caching
Mongoose supports query caching to improve performance:
javascriptconst userSchema = new Schema({ name: String, email: String }, { query: { cache: true } }); // Enable caching const users = await User.find().cache(); // Set cache time const users = await User.find().cache(60); // 60 seconds
Best Practices
- Create indexes for frequently queried fields
- Use
select()to query only needed fields - Use
lean()for read-only queries to improve performance - Use pagination to avoid querying large amounts of data
- Avoid executing queries in loops
- Use batch operations instead of multiple single operations
- Monitor query performance and optimize slow queries
- Use
explain()to analyze query plans