MongoDB实现四层Group By嵌套分组及按合作方拼接时间咨询
MongoDB 多层嵌套分组实现方案
一、多层级分组聚合逻辑
你需要通过三次$group阶段从细粒度到粗粒度逐步聚合,即可得到你要的四层嵌套结构:
- 第一层先按「项目+合作方+日期」三个维度分组,先把同维度下的时间归集为数组
- 第二层按「项目+合作方」维度分组,把同合作方下的日期和对应时间数组归集为列表
- 第三层按「项目」维度分组,把同项目下的合作方及对应日期时间数据归集为列表
聚合管道完整代码
如果你的原始数据字段名和示例不同,替换$group阶段里对应的字段名即可。
db.collection.aggregate([ // 第一步:归集同项目、同合作方、同日期下的所有时间 { $group: { _id: { projectName: "$projectName", partnerName: "$partnerName", date: "$date" }, times: { $push: "$time" } } }, // 第二步:归集同项目、同合作方下的所有日期+时间数据 { $group: { _id: { projectName: "$_id.projectName", partnerName: "$_id.partnerName" }, dates: { $push: { date: "$_id.date", times: "$times" } } } }, // 第三步:归集同项目下的所有合作方数据 { $group: { _id: "$_id.projectName", partners: { $push: { partnerName: "$_id.partnerName", dates: "$dates" } } } }, // 可选:重命名最外层字段,更符合命名习惯 { $project: { _id: 0, projectName: "$_id", partners: 1 } } ])
二、合作方维度拼接时间值
如果需要把每个合作方下的所有时间拼接为单个字符串,可在第二步分组后新增$addFields阶段实现,示例如下:
// 在上述聚合管道的第二步和第三步之间插入以下阶段 { $addFields: { // 先把合作方下所有日期的时间数组合并为一个数组 allTimes: { $reduce: { input: "$dates", initialValue: [], in: { $concatArrays: ["$$value", "$$this.times"] } } } } }, // 再把数组合并为逗号分隔的字符串,可自行替换分隔符 { $addFields: { mergedPartnerTimes: { $reduce: { input: "$allTimes", initialValue: "", in: { $cond: { if: { $eq: ["$$value", ""] }, then: "$$this", else: { $concat: ["$$value", ",", "$$this"] } } } } } } }
返回结构说明
最终返回的层级和你要求的完全匹配,嵌套关系为:
ProjectName └─ PartnerName └─ Date └─ 时间数组
内容的提问来源于stack exchange,提问作者2Fast4YouBR
相关产品推荐
相关产品推荐

