条件查询与复杂过滤
条件查询基础
Mongoose提供了丰富的查询方法,最基本的是find()
方法。它接受一个条件对象作为参数,返回匹配该条件的所有文档。
const User = mongoose.model('User', userSchema);
// 查找所有年龄大于18的用户
User.find({ age: { $gt: 18 } })
.then(users => console.log(users))
.catch(err => console.error(err));
常用比较操作符包括:
$eq
: 等于$ne
: 不等于$gt
: 大于$gte
: 大于等于$lt
: 小于$lte
: 小于等于$in
: 在数组中$nin
: 不在数组中
逻辑操作符组合查询
Mongoose支持使用逻辑操作符组合多个条件,实现更复杂的查询逻辑。
// 查找年龄在18到30之间,或者名字为"张三"的用户
User.find({
$or: [
{ age: { $gte: 18, $lte: 30 } },
{ name: '张三' }
]
}).exec();
主要逻辑操作符:
$and
: 逻辑与$or
: 逻辑或$nor
: 逻辑非或$not
: 逻辑非
数组条件查询
当查询包含数组的字段时,Mongoose提供了专门的操作符来处理数组查询。
const Post = mongoose.model('Post', postSchema);
// 查找标签包含"技术"的文章
Post.find({ tags: '技术' }).exec();
// 查找标签同时包含"技术"和"编程"的文章
Post.find({ tags: { $all: ['技术', '编程'] } }).exec();
// 查找tags数组长度为3的文章
Post.find({ tags: { $size: 3 } }).exec();
数组专用操作符:
$all
: 包含所有指定元素$elemMatch
: 数组元素匹配所有条件$size
: 数组长度匹配
嵌套文档查询
对于嵌套文档或对象类型的字段,可以使用点表示法进行查询。
const Order = mongoose.model('Order', orderSchema);
// 查找送货地址城市为"北京"的订单
Order.find({ 'shipping.address.city': '北京' }).exec();
// 使用$elemMatch查询嵌套数组
Order.find({
items: {
$elemMatch: {
product: '手机',
quantity: { $gte: 2 }
}
}
}).exec();
正则表达式查询
Mongoose支持使用正则表达式进行模糊查询,特别适合文本搜索。
// 查找名字以"张"开头的用户
User.find({ name: /^张/ }).exec();
// 使用RegExp对象,不区分大小写
User.find({ name: new RegExp('wang', 'i') }).exec();
分页与排序
结合条件查询,通常需要实现分页和排序功能。
const page = 1;
const limit = 10;
User.find({ active: true })
.sort({ createdAt: -1 }) // 按创建时间降序
.skip((page - 1) * limit) // 跳过前面的记录
.limit(limit) // 限制返回数量
.exec();
聚合查询
对于更复杂的数据分析和统计,可以使用Mongoose的聚合框架。
User.aggregate([
{ $match: { age: { $gte: 18 } } }, // 条件筛选
{ $group: {
_id: '$city',
total: { $sum: 1 },
avgAge: { $avg: '$age' }
} }, // 按城市分组统计
{ $sort: { total: -1 } }, // 按总数降序
{ $limit: 5 } // 只返回前5条
]).exec();
查询性能优化
针对大型数据集,查询性能优化至关重要。
- 索引优化:
userSchema.index({ name: 1 }); // 单字段索引
userSchema.index({ age: 1, city: 1 }); // 复合索引
- 选择性查询:只查询需要的字段
User.find({}, 'name email').exec(); // 只返回name和email字段
- 使用
lean()
:返回普通JS对象而非Mongoose文档,减少开销
User.find().lean().exec();
链式查询构建
Mongoose查询支持链式调用,可以动态构建查询条件。
const query = User.find();
// 根据条件动态添加查询
if (minAge) {
query.where('age').gte(minAge);
}
if (maxAge) {
query.where('age').lte(maxAge);
}
if (namePattern) {
query.where('name').regex(new RegExp(namePattern, 'i'));
}
query.exec().then(users => {
// 处理结果
});
高级查询技巧
- 使用
$where
:可以执行JavaScript表达式
User.find({ $where: 'this.age > this.minAge + 5' }).exec();
- 地理空间查询:对于包含地理坐标的数据
const Place = mongoose.model('Place', placeSchema);
Place.find({
location: {
$near: {
$geometry: {
type: 'Point',
coordinates: [longitude, latitude]
},
$maxDistance: 1000 // 1公里范围内
}
}
}).exec();
- 文本搜索:需要先创建文本索引
postSchema.index({ content: 'text' });
Post.find({ $text: { $search: '数据库 优化' } })
.sort({ score: { $meta: 'textScore' } })
.exec();
本站部分内容来自互联网,一切版权均归源网站或源作者所有。
如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn
上一篇:批量操作与高效写入
下一篇:什么是 uni-app