MongoDB聚合:按数组元素分组并按比例分配求和
按数组元素位置分配权重并分组求和的MongoDB解决方案
没问题,我帮你搞定这个MongoDB的分组求和需求!我们可以用MongoDB的聚合框架来精准实现你要的权重分配逻辑——给数组首尾元素各分配40%的total权重,中间元素平分剩余20%,最后按value分组累加。
核心思路拆解
- 先计算每个文档数组的长度,以及中间元素的单个权重(剩余20%除以中间元素的数量)
- 给数组里的每个元素标记对应的权重(首/尾为2/5,中间为计算出的单个权重)
- 展开数组,计算每个元素对总结果的贡献值(total × 权重)
- 按value分组,累加所有贡献值得到最终结果
完整聚合查询代码
db.collection.aggregate([ // 第一步:计算数组长度和中间元素的单个权重 { $addFields: { arrayLength: { $size: "$myArray" }, middleElementWeight: { $cond: [ { $gt: [{ $size: "$myArray" }, 2] }, { $divide: [1/5, { $subtract: [{ $size: "$myArray" }, 2] }] }, 0 ] } } }, // 第二步:给每个数组元素添加对应的权重 { $addFields: { myArrayWithWeight: { $map: { input: "$myArray", as: "item", in: { value: "$$item.value", weight: { $switch: { branches: [ // 第一个元素:分配40%(2/5)权重 { case: { $eq: [{ $indexOfArray: ["$myArray", "$$item"] }, 0] }, then: 2/5 }, // 最后一个元素:分配40%(2/5)权重 { case: { $eq: [{ $indexOfArray: ["$myArray", "$$item"] }, { $subtract: ["$arrayLength", 1] }] }, then: 2/5 } ], // 中间元素:平分剩余20%(1/5)的权重 default: "$middleElementWeight" } } } } } } }, // 第三步:展开数组,让每个元素成为独立文档 { $unwind: "$myArrayWithWeight" }, // 第四步:计算每个元素的贡献值 { $addFields: { contribution: { $multiply: ["$total", "$myArrayWithWeight.weight"] } } }, // 第五步:按value分组,累加所有贡献值 { $group: { _id: "$myArrayWithWeight.value", total: { $sum: "$contribution" } } }, // 可选:格式化total为保留两位小数的数值(提升可读性) { $addFields: { total: { $round: ["$total", 2] } } } ])
结果验证
针对你提供的示例文档,运行上述查询后会得到符合预期的结果:
_id: "a"的total为7.02(对应(2/5*5.8 + 2/5*5.8 + 1/20*5.8 + 1/20*5.8) + 2/5*4.5 = 5.22 + 1.8 = 7.02)_id: "b"的total为0.29(对应1/20*5.8)_id: "c"的total为2.99(对应1/20*5.8 + 1/5*4.5 + 2/5*4.5 = 0.29 + 2.7 = 2.99)
内容的提问来源于stack exchange,提问作者Dr. Mza
相关产品推荐
相关产品推荐

