聚合以从文档和数组元素中获取平均值

Aggregate to get average from document and of array elements

我得到了这些对象的数组:

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 stages since you pushed arrays inside an array and then follow up with two $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"
        }}
    }}
])

所以先在"type"层进行分组,得到的结果可以得到跨元素的平均值,然后重构原始形式。注意$sort要保留元素的顺序,否则会颠倒:

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

如果您想首先 $unwind 避免将数组放在数组中,那么请不要这样做。您在数组外寻找的平均值将受到展开时数组中元素数量的影响。因此,一个文档中包含更多元素的数组到另一个文档中会 "weight" 它们在确定那里的平均值时的价值更高。