如何在MongoDB集合聚合的Lookup中引用Settings集合的年份值
问题场景
现有三个MongoDB集合:
- settings集合:包含一个
_name为"A"的文档,存储目标年份:
"settings" : [ { _id: ObjectId('123123123123'), _name: "A", data: { year: 2025 } } ]
- B集合:存储待关联的基础数据:
"B": [ { shortName: "B1" }, { shortName: "B2" } ]
- A集合:存储需按年份过滤的关联数据:
"A" : [ { name: "A2", shortNameInA: "B1", datesInfo: { closed: ISODate("2025-12-10"), } }, { name: "A3", shortNameInA: "B2", datesInfo: { report: ISODate("2025-03-10"), } }, { name: "A1", shortNameInA: "B1", datesInfo: { closed: ISODate("2024-12-10"), } } ]
需要在B集合的聚合查询中,将原查询里的$$NOW替换为settings集合中data.year的值(2025),实现按目标年份过滤A集合的关联数据。
解决方案
核心思路是先从settings集合获取目标年份,再将该年份作为变量传递给关联A集合的子管道进行过滤,完整聚合代码如下:
db.B.aggregate([ // 1. 获取settings中的目标年份数据 { $lookup: { from: "settings", pipeline: [{ $match: { _name: "A" } }], as: "settingsData" } }, // 展开settings数组(因仅匹配一个文档) { $unwind: "$settingsData" }, // 提取目标年份到独立字段 { $addFields: { targetYear: "$settingsData.data.year" } }, // 2. 关联A集合并按目标年份过滤 { $lookup: { from: "A", localField: "shortName", foreignField: "shortNameInA", let: { targetYear: "$targetYear" }, // 将目标年份传入子管道 pipeline: [ { $match: { $expr: { $or: [ { $eq: [{ $year: "$datesInfo.closed" }, "$$targetYear"] }, { $eq: [{ $year: "$datesInfo.report" }, "$$targetYear"] } ] } } } ], as: "_fromA" } }, // 清理临时字段,返回整洁结果 { $project: { settingsData: 0, targetYear: 0 } } ])
预期结果
执行上述聚合后,将得到按目标年份过滤的关联结果:
[ { shortName: "B1", _fromA: [ { name: "A2", shortNameInA: "B1", datesInfo: { closed: ISODate("2025-12-10"), } } ] }, { shortName: "B2", _fromA: [ { name: "A3", shortNameInA: "B2", datesInfo: { report: ISODate("2025-03-10"), } } ] } ]
内容的提问来源于stack exchange,提问作者richnwilson
相关产品推荐
相关产品推荐

