如何按Mongoose内嵌关联对象属性查询MongoDB集合文档
可行解决方案
方案1:两步查询(性能最优,推荐优先使用)
先查询符合fleet条件的用户ID,再用ID过滤UserQualification集合,避免关联查询的额外开销:
// 步骤1:查询所有fleet满足条件的用户ID const matchedUserIds = await User.find({ fleet: { $in: ["FleetA", "FleetC"] } }).lean().select('_id'); // 步骤2:用用户ID列表筛选UserQualification文档 const qualificationList = await UserQualification.find({ user: { $in: matchedUserIds.map(item => item._id) } });
方案2:聚合管道单步查询(适合需要同时返回关联用户信息的场景)
通过$lookup关联用户集合后直接过滤:
const qualificationList = await UserQualification.aggregate([ { $lookup: { from: "users", // 对应MongoDB中User模型对应的集合名,默认是模型名小写加s localField: "user", foreignField: "_id", as: "user" } }, // 拆分关联得到的单元素数组为对象 { $unwind: "$user" }, // 匹配fleet条件 { $match: { "user.fleet": { $in: ["FleetA", "FleetC"] } } } ])
常见问题说明
你之前用populate加查询条件没有得到预期结果的原因是:populate的match参数仅用于过滤关联返回的文档,不会过滤主集合的UserQualification文档,只会把不符合条件的关联user字段设为null,主文档还是会全部返回。如果一定要用populate实现可以额外加一层过滤,但性能远低于前两种方案,不推荐:
// 不推荐,仅作原理参考 const qualificationList = await UserQualification.find() .populate({ path: "user", match: { fleet: { $in: ["FleetA", "FleetC"] } } }) .then(docs => docs.filter(doc => doc.user != null));
内容的提问来源于stack exchange,提问作者Matt Price
相关产品推荐
相关产品推荐

