Mongoose 提供了强大的查询构建器,支持链式调用和丰富的查询操作,使 MongoDB 查询更加直观和易用。
基本查询
查找所有文档
javascriptconst users = await User.find();
条件查询
javascript// 等于 const users = await User.find({ age: 25 }); // 不等于 const users = await User.find({ age: { $ne: 25 } }); // 大于 const users = await User.find({ age: { $gt: 18 } }); // 大于等于 const users = await User.find({ age: { $gte: 18 } }); // 小于 const users = await User.find({ age: { $lt: 30 } }); // 小于等于 const users = await User.find({ age: { $lte: 30 } }); // 在数组中 const users = await User.find({ status: { $in: ['active', 'pending'] } }); // 不在数组中 const users = await User.find({ status: { $nin: ['deleted'] } });
逻辑操作符
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' } ] });
链式查询
选择字段
javascript// 只选择特定字段 const users = await User.find() .select('name email age'); // 排除特定字段 const users = await User.find() .select('-password -__v'); // 使用对象语法 const users = await User.find() .select({ name: 1, email: 1, age: 1 });
排序
javascript// 升序 const users = await User.find() .sort({ name: 1 }); // 降序 const users = await User.find() .sort({ age: -1 }); // 多字段排序 const users = await User.find() .sort({ status: 1, age: -1 });
限制和跳过
javascript// 限制结果数量 const users = await User.find() .limit(10); // 跳过指定数量 const users = await User.find() .skip(5); // 分页 const page = 2; const pageSize = 10; const users = await User.find() .skip((page - 1) * pageSize) .limit(pageSize);
高级查询
正则表达式
javascript// 包含 const users = await User.find({ name: /john/i }); // 以开头 const users = await User.find({ name: /^john/i }); // 以结尾 const users = await User.find({ name: /doe$/i });
数组查询
javascript// 数组包含特定值 const users = await User.find({ tags: 'javascript' }); // 数组包含多个值(AND) const users = await User.find({ tags: { $all: ['javascript', 'nodejs'] } }); // 数组大小 const users = await User.find({ tags: { $size: 3 } });
嵌套文档查询
javascript// 嵌套字段查询 const users = await User.find({ 'address.city': 'New York' }); // 嵌套数组查询 const users = await User.find({ 'orders.status': 'completed' });
元素查询
javascript// 字段存在 const users = await User.find({ email: { $exists: true } }); // 字段类型 const users = await User.find({ age: { $type: 'number' } });
聚合查询
javascript// 分组统计 const result = await User.aggregate([ { $match: { age: { $gte: 18 } } }, { $group: { _id: '$status', count: { $sum: 1 } } } ]); // 查找并修改 const user = await User.findOneAndUpdate( { email: 'john@example.com' }, { age: 25 }, { new: true } );
查询优化
使用索引
javascriptconst userSchema = new Schema({ email: { type: String, index: true }, age: { type: Number, index: true } }); // 复合索引 userSchema.index({ email: 1, age: -1 });
投影优化
javascript// 只查询需要的字段 const users = await User.find() .select('name email');
使用 lean()
javascript// 返回普通 JavaScript 对象,性能更好 const users = await User.find().lean();
批量操作
javascript// 批量插入 const users = await User.insertMany([ { name: 'John', email: 'john@example.com' }, { name: 'Jane', email: 'jane@example.com' } ]); // 批量更新 const result = await User.updateMany( { status: 'pending' }, { status: 'active' } );
查询缓存
Mongoose 支持查询缓存以提高性能:
javascriptconst userSchema = new Schema({ name: String, email: String }, { query: { cache: true } }); // 启用缓存 const users = await User.find().cache(); // 设置缓存时间 const users = await User.find().cache(60); // 60秒
最佳实践
- 为常用查询字段创建索引
- 使用
select()只查询需要的字段 - 对于只读查询使用
lean()提高性能 - 合理使用分页避免查询大量数据
- 避免在循环中执行查询
- 使用批量操作代替多次单条操作
- 监控查询性能,优化慢查询
- 使用
explain()分析查询计划