MongoDB按每4个元素分组数组:实现日维度数据聚合
解决方案
当然可以实现!从你给出的预期结果反推,你应该是想把someField数组按每4个元素为一组,提取每组的最大值来组成新数组对吧?咱们用MongoDB的聚合框架就能轻松搞定,具体的聚合管道如下:
db.yourCollection.aggregate([ // 展开someField数组,同时记录每个元素的索引位置 { $unwind: { path: "$someField", includeArrayIndex: "index" } }, // 计算每个元素所属的分组(每4个一组) { $addFields: { groupId: { $floor: { $divide: ["$index", 4] } } } }, // 按文档_id和分组ID分组,计算每组的最大值 { $group: { _id: { docId: "$_id", group: "$groupId" }, maxVal: { $max: "$someField" } } }, // 按分组ID排序,保证顺序和原数组一致 { $sort: { "_id.group": 1 } }, // 重新按文档_id分组,将最大值收集为新的someField数组 { $group: { _id: "$_id.docId", someField: { $push: "$maxVal" } } } ])
步骤解释:
- $unwind阶段:把
someField数组拆分成单个元素,同时用includeArrayIndex参数记录每个元素在原数组中的索引位置,这是后续分组的关键依据。 - $addFields阶段:通过
$divide将索引除以4,再用$floor取整数部分,得到每个元素所属的分组ID(比如索引0-3对应groupId 0,4-7对应groupId 1,以此类推)。 - 第一次$group阶段:按文档的
_id和分组ID进行分组,用$max聚合操作符提取每组的最大值,完成每组的聚合计算。 - $sort阶段:确保分组结果按分组ID升序排列,保证新生成的
someField数组顺序和原数组的分组顺序一致。 - 第二次$group阶段:将同一个文档的所有分组最大值收集成新的
someField数组,恢复成你需要的文档结构。
如果你的需求不是取最大值,而是其他聚合逻辑(比如平均值、求和),只需要把$max换成对应的聚合操作符即可(例如$avg、$sum)。
内容的提问来源于stack exchange,提问作者Soni007
相关产品推荐
相关产品推荐

