我有这些对象的数组:
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}
]
};
它们都有相同的数组,相同的类型“a”、“b”和“c”,但值不同。
如何获取类型“a”、“b”和“c”的平均值?
如何获取所有项目的平均值?
期待
itemAvg = {
name:'item',
val:3,
list:[
{type:'a',value:2},
{type:'b',value:50},
{type:'c',value:1}
]
};
我想首先按名称和推送列表对 val 进行分组。 然后展开列表。 然后按类型对列表进行分组。
但这行不通
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'}
}}
])
我希望展开后的最后一组将按曲调类型分组并计算每种不同类型的平均值...但是没有...我得到 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"
}}
}}
])
所以首先在“类型”级别分组,得到的结果可以得到元素之间的平均值,然后重构原始形式。注意 $sort
保留元素的顺序,否则会颠倒:
{
"_id" : "name",
"val" : 3,
"list" : [
{
"type" : "a",
"value" : 2
},
{
"type" : "b",
"value" : 50
},
{
"type" : "c",
"value" : 1
}
]
}
如果您想要先$unwind
以避免将数组放在数组中,那么请不要这样做。您在数组外寻找的平均值将受到展开时数组中元素数量的影响。因此,一个文档中包含更多元素的数组到另一个文档中会在确定平均值时更高地“加权”它们的值。
关于node.js - 聚合以从文档和数组元素中获取平均值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28976643/