从文档和数组元素聚合得到平均值

我有这些对象的数组:

item1 = { name:'item', val:1, list:[ {type:'a',value:1}, {type:'b',value:1}, {type:'c',value:1} ] }; item2 = { name:'item', val:5, list:[ {type:'a',value:3}, {type:'b',value:99}, {type:'c',value:1} ] }; 

他们都有相同的数组,相同的types“a”,“b”和“c”,但不同的值。

我怎样才能得到types“a”,“b”和“c”的平均值?

我怎样才能得到所有项目的平均价值?

我期待着

 itemAvg = { name:'item', val:3, list:[ {type:'a',value:2}, {type:'b',value:50}, {type:'c',value:1} ] }; 

我认为首先按名称分组,然后按列表。 然后展开列表。 然后按types对列表进行分组。

但是这不起作用

 model.aggregate([ { $match : <condition> }, { $group : { _id:{name:'$name'}, ValAvg:{$avg:'$val'} List:{$push:'list'} }}, { $unwind:'$List'}, { $group:{ _id:{type:'$List.type', ValueAvg:{$avg:'$List.value'} }} ]) 

我希望在放松后的最后一组将按照调整types进行分组,并计算每种不同types的值的平均值…但是没有…我得到ValueAvg = 0

谢谢

你需要两个$unwind阶段,因为你把数组放在一个数组中,然后跟着两个$group阶段:

 model.aggregate([ { "$match": { <condition> }}, { "$group": { "_id": "name", "val": { "$avg": "$val" }, "list": { "$push": "$list" } }}, { "$unwind": "$list" }, { "$unwind": "$list" }, { "$group": { "_id": { "name": "$_id", "type": "$list.type" }, "val": { "$avg": "$val" }, "valAvg": { "$avg": "$list.value" } }}, { "$sort": { "_id": 1 } }, { "$group": { "_id": "$_id.name", "val": { "$avg": "$val" }, "list": { "$push": { "type": "$_id.type", "value": "$valAvg" }} }} ]) 

因此,通过在“types”级别进行分组,首先获得的结果可以获得元素的平均值,然后重构原始forms。 注意$sort保留元素的顺序,否则会颠倒过来:

 { "_id" : "name", "val" : 3, "list" : [ { "type" : "a", "value" : 2 }, { "type" : "b", "value" : 50 }, { "type" : "c", "value" : 1 } ] } 

如果您试图先放开$unwind以避免将数组放在数组中,那么不要这样做。 在数组之外寻找的平均值将受数组中元素数目的影响。 因此,将一个文档中的元素排列在另一个文档中将会更加“重视”它们的价值,从而确定其中的平均值。