使用$ group时,有没有办法使用加权平均值而不是$ avg组累加器?我使用此(How do I calculate a weighted average in mongoDB using aggregation framework?)作为加权平均值,但我得到的错误是"字段' id:WAVG_A'必须指定一个累加器"。是否有某种黑客使用投影而不是群累加器?
我的聚合JSON的一个子集在这里:
{
"$group":{
"_id":{
"id:DIM_1":"$id:DIM_1",
"id:DIM_2":"$id:DIM_2"
},
"id:WAVG_A":{
"$group":{
"_id":"weighted average",
"nu":{
"$sum":{
"$multiply":[
"$id:WAVG_A",
"$id:MET_A"
]
}
},
"de":{
"$sum":"$id:MET_A"
}
},
"$project":{
"average":{
"$divide":[
"$nu",
"$de"
]
}
}
},
"id:MET_A":{
"$sum":"$id:MET_A"
}
}
}
修改
为了简化操作,让我尝试使用类似于mongo站点上提供的示例的数据来解释我的问题。假设您有以下数据:
{ "_id" : 1, "item" : "abc", "price" : 10, "quantity" : 2, "weight" : 1, "date" : ISODate("2014-03-01T08:00:00Z") }
{ "_id" : 2, "item" : "jkl", "price" : 20, "quantity" : 1, "weight" : 1, "date" : ISODate("2014-03-01T09:00:00Z") }
{ "_id" : 3, "item" : "xyz", "price" : 5, "quantity" : 10, "weight" : 2, "date" : ISODate("2014-03-15T09:00:00Z") }
{ "_id" : 4, "item" : "xyz", "price" : 5, "quantity" : 20, "weight" : 3, "date" : ISODate("2014-04-04T11:21:39.736Z") }
{ "_id" : 5, "item" : "abc", "price" : 10, "quantity" : 10, "weight" : 3, "date" : ISODate("2014-04-04T21:23:13.331Z") }
在汇总数据时,您不想使用$ avg,而是希望使用加权平均值(https://support.microsoft.com/en-ca/help/214049/how-to-calculate-weighted-averages-in-excel)。如果原生支持,它可能看起来像:
db.sales.aggregate(
[
{
$group : {
_id : { month: { $month: "$date" }, day: { $dayOfMonth: "$date" }, year: { $year: "$date" } },
totalPrice: { $sum: { $multiply: [ "$price", "$quantity" ] } },
averageQuantity: { $weighted_avg: { $value : "$quantity", $weight: "$weight" },
count: { $sum: 1 }
}
}
]
)
这个想法是,当你平均它时,你有平均值和重量。 Mongo支持加权平均值,因为它根据How do I calculate a weighted average in mongoDB using aggregation framework?支持乘法和除法等数学运算。但我无法弄清楚在汇总数据时如何使用加权平均值。当我想使用$ group时,如何应用How do I calculate a weighted average in mongoDB using aggregation framework?的答案。答案的问题在于它是$ group和$ project,你似乎无法将其用作$ group的累加器。
答案 0 :(得分:0)
所以我解决了我的问题。我试图立刻做太多。我的解决方案是将组和项目拆分为两个单独的步骤,同时将分子和分母放入临时值并且它有效。
{
"$group":{
"_id":{
"id:DIM_1":"$id:DIM_1",
"id:DIM_2":"$id:DIM_2"
},
"id:WAVG_A??num":{
"$sum":{
"$multiply":[
"$id:WAVG_A",
"$id:MET_A"
]
}
},
"id:WAVG_A??den":{
"$sum":"$id:MET_A"
},
"id:MET_A":{
"$sum":"$id:MET_A"
}
}
}
然后
{
"$project":{
"id:DIM_1":"$_id.id:DIM_1",
"id:DIM_2":"$_id.id:DIM_2",
"id:WAVG_A":{
"$cond":[
{
"$eq":[
"$id:WAVG_A??den",
0
]
},
0,
{
"$divide":[
"$id:WAVG_A??num",
"$id:WAVG_A??den"
]
}
]
},
"id:MET_A":"$id:MET_A"
}