从budgets集合聚合关联customers并返回无预算客户的实现方法
MongoDB聚合实现:从Budgets集合出发关联客户与预算数据(含无预算客户)
需求说明
从budgets集合启动聚合操作,最终返回所有客户数据:
- 有预算关联的客户,其
Budgets字段为对应预算数据的数组 - 无预算关联的客户,
Budgets字段为空数组 - 返回结构需符合给定的客户数据格式
聚合管道实现
假设budgets集合通过customerId字段关联customers集合的Id字段,完整聚合代码如下:
db.budgets.aggregate([ // 1. 按客户ID分组,归集该客户的所有预算数据 { $group: { _id: "$customerId", Budgets: { $push: "$$ROOT" } } }, // 2. 左连接customers集合,匹配对应客户信息 { $lookup: { from: "customers", localField: "_id", foreignField: "Id", as: "customer" } }, // 3. 展开客户数组(每个分组仅匹配一个客户) { $unwind: "$customer" }, // 4. 合并客户数据与预算数组,构造目标结构 { $replaceRoot: { newRoot: { $mergeObjects: ["$customer", { Budgets: "$Budgets" }] } } }, // 5. 合并无预算的客户数据 { $unionWith: { coll: "customers", pipeline: [ { $lookup: { from: "budgets", localField: "Id", foreignField: "customerId", as: "temp" } }, { $match: { temp: { $size: 0 } } }, { $addFields: { Budgets: [] } }, { $project: { temp: 0 } } ] } } ])
步骤解析
- $group:将同属一个客户的预算文档分组,把所有预算数据存入
Budgets数组,分组依据为客户关联ID。 - $lookup:通过客户ID关联
customers集合,拉取对应客户的完整数据。 - $unwind:展开
lookup返回的客户数组,得到单个客户对象。 - $replaceRoot:将客户基础数据与预算数组合并,作为最终返回的根文档,贴合需求格式。
- $unionWith:补充无预算的客户数据——子管道先排查客户是否有关联预算,筛选出无预算的客户后,给其添加空的
Budgets数组,再与前面的有预算客户数据合并。
注意事项
- 若实际集合中关联字段名与示例不同(比如
budgets用CustomerId而非customerId),需同步修改管道中对应的字段名称。 - 确保
customers集合的客户ID字段为Id,若使用MongoDB默认的_id,需调整lookup阶段的foreignField参数。
内容的提问来源于stack exchange,提问作者DValdir Martins
相关产品推荐
相关产品推荐

