如何在MongoDB中查询关联站点且排除维护站点的组件
解决方案:排除所属站点处于维护状态的组件
要实现你想要的效果,我们只需要在原聚合查询的基础上,添加过滤逻辑排除掉所属站点存在维护记录的组件。这里提供两种实用的方案,你可以根据数据规模和性能需求选择:
方案一:聚合流程内完成过滤(单查询)
这种方案不需要额外的前置查询,直接在聚合管道里关联维护集合并过滤:
componentCollection.aggregate([ // 关联维护集合,获取组件所属站点的维护记录 { $lookup: { from: 'maintenance', localField: 'siteId', foreignField: 'siteId', as: 'maintenance' } }, // 过滤掉有维护记录的组件(只保留维护记录为空的) { $match: { maintenance: { $size: 0 } } }, // 关联站点信息(和你原查询逻辑一致) { $lookup: { from: 'sites', localField: 'siteId', foreignField: '_id', as: 'sites' } } ])
逻辑说明:
- 关联维护集合:通过
siteId匹配组件所属站点的维护记录,结果存入maintenance数组。如果站点在维护中,数组会有对应记录;否则为空。 - 过滤维护组件:用
$match结合$size: 0筛选出maintenance为空的组件,也就是所属站点无维护记录的。 - 关联站点信息:和你原查询逻辑一致,获取组件对应的站点详情。
方案二:先获取维护站点ID再过滤(性能更优)
如果维护站点数量不多,这种方案性能更好——先查出所有维护中的站点ID,再直接过滤组件:
// 先从维护集合提取所有维护中的站点ID const maintenanceSiteIds = await maintenanceCollection.distinct('siteId'); // 执行聚合查询,先过滤再关联站点 componentCollection.aggregate([ // 过滤掉所属站点在维护列表中的组件 { $match: { siteId: { $nin: maintenanceSiteIds } } }, // 关联站点信息 { $lookup: { from: 'sites', localField: 'siteId', foreignField: '_id', as: 'sites' } } ])
逻辑说明:
- 获取维护站点ID列表:用
distinct快速提取所有维护状态的siteId。 - 过滤组件:通过
$nin(不在列表内)筛选出所属站点不在维护列表的组件。 - 关联站点信息:和原查询逻辑一致,获取站点详情。
结果验证
针对你提供的示例数据,两种方案都会返回期望结果:
[ { _id: 4, siteId: 2, details: 'footer links', sites: [ { _id: 2, name: 'site2' } ] } ]
内容的提问来源于stack exchange,提问作者Piccaza De
相关产品推荐
相关产品推荐

