MongoDB聚合框架:按数组值分组并实现线性分配求和
实现MongoDB数组元素的线性归因求和
当然可以用MongoDB聚合框架实现这个需求,虽然没有单一的内置函数直接完成,但通过组合几个聚合阶段就能轻松达成。下面是具体的实现思路和代码:
核心思路拆解
要完成线性分配求和,我们需要分四步处理:
- 先计算每个文档中
myArray的元素数量,这样才能算出每个元素应分配的total比例(total / 数组长度) - 将数组展开,让每个
myArray元素成为独立的文档 - 为每个展开后的元素计算对应的分配值
- 按
value分组,累加所有对应分配值得到最终结果
完整聚合管道代码
db.collection.aggregate([ // 步骤1:添加数组长度字段,用于计算分配比例 { $addFields: { arrayLength: { $size: "$myArray" } } }, // 步骤2:展开数组,每个元素单独成文档 { $unwind: "$myArray" }, // 步骤3:计算当前元素对应的分配值(total / 数组长度) { $addFields: { allocatedValue: { $divide: ["$total", "$arrayLength"] } } }, // 步骤4:按value分组,累加分配值得到线性求和结果 { $group: { _id: "$myArray.value", linear_total: { $sum: "$allocatedValue" } } }, // 可选:格式化结果,让字段更清晰(比如保留小数位数) { $project: { _id: 1, linear_total: { $round: ["$linear_total", 3] } // 保留3位小数,可按需调整 } } ])
结果验证
针对你给出的示例文档,运行上述管道后会得到:
[ { "_id": "a", "linear_total": 5.367 }, // 4/6*5.8 + 1/3*4.5 ≈ 3.867 + 1.5 = 5.367 { "_id": "b", "linear_total": 0.967 }, // 1/6*5.8 ≈ 0.967 { "_id": "c", "linear_total": 3.967 } // 1/6*5.8 + 2/3*4.5 ≈ 0.967 + 3 = 3.967 ]
补充说明
- 如果你的
myArray可能为空,建议在$addFields阶段添加判断(比如用$cond处理数组长度为0的情况,避免除以0错误) - 若需要更精确的小数结果,可以去掉
$project中的$round,或者调整保留的小数位数
内容的提问来源于stack exchange,提问作者Dr. Mza
相关产品推荐
相关产品推荐

