MongoDB聚合:实现数组元素与非数组元素的除法运算
解决MongoDB聚合中数组元素计算占比的问题
你的问题出在:直接使用$projects.cost时,MongoDB会把它解析成整个数组中所有元素的cost字段组成的数组,而$divide无法直接用数组和单个数值做除法运算,所以没法得到每个项目的占比。
正确的实现方式
需要用$map遍历projects数组,对每个元素单独计算占比,同时保留原有字段。推荐用$mergeObjects来合并原有字段和新计算的占比,避免手动重复写所有字段:
stage_add_percentage_revenue = { "$addFields": { "projects": { "$map": { "input": "$projects", "as": "proj", "in": { "$mergeObjects": [ "$$proj", # 保留当前项目的所有原有字段 { # 计算当前项目成本占总费用的比例 "percentage_revenue": { "$divide": ["$$proj.cost", "$total_project_cost"] } } ] } } } } }
代码说明
$map:遍历projects数组,$$proj指代数组中的当前项目元素$mergeObjects:把原有项目的所有字段和新生成的percentage_revenue字段合并,避免重复编写每个字段$$proj.cost:访问当前项目的cost字段,和全局的$total_project_cost做除法得到占比
执行后的结果示例
{ "total_project_cost": 13200.0, "total_hours": 120.0, "total_salaries": 0, "projects": [ { "_id": "id1", "name": "Project1", "cost": 5610.0, "duration": 51.0, "salaries": 0, "gross_profit": 5610.0, "percentage_revenue": 0.425 }, { "_id": "id2", "name": "Project2", "cost": 7590.0, "duration": 69.0, "salaries": 0, "gross_profit": 7590.0, "percentage_revenue": 0.575 } ], "total_gross_profit": 13200.0, "date": { "year": 2022, "month": 8 } }
如果需要把占比格式化为百分比(比如保留两位小数),可以套一层$round:
"percentage_revenue": { "$round": [ {"$divide": ["$$proj.cost", "$total_project_cost"]}, 2 ] }
内容的提问来源于stack exchange,提问作者Timothee W
相关产品推荐
相关产品推荐

