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

时间:2015-03-11 00:42:26

标签: node.js mongodb mongoose mongodb-query aggregation-framework

我有这些对象的数组:

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

由于

1 个答案:

答案 0 :(得分:1)

您需要两个$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以避免将数组放入数组中,那么请不要这样做。您在阵列外寻找的平均值将受到展开时阵列中元素数量的影响。因此,在一个文档中具有更多元素的数组到另一个文档中的数组将在确定其平均值时“加权”它们的值。