从mongodb $ avg中排除0值,但保留其他字段

时间:2016-05-31 15:45:48

标签: mongodb aggregation-framework

我在MongoDB 3.2上运行了一些聚合查询。 我想按一个字段对文档进行分组,其中包含另一个数字字段的平均值。 我需要平均值忽略0值。 问题是我无法完全过滤文档,因为我需要另一个字段进行计数。

让我们来说明一下:

这是我的文件结构:

{"stringToGroupByOn":"foo", "valueToAvg":42, "valueToSum":21}
{"stringToGroupByOn":"foo", "valueToAvg":0, "valueToSum":13}

我不能像这样过滤:

db.foobar.aggregate([
    { 
        $match : { valueToAvg : { $gt : 0 } } 
    },
    { 
        $group : {
            _id : '$stringToGroupByOn',
            avg : { $avg :  '$valueToAvg' }, 
            count : { $sum : '$valueToSum' }
        }
    }
])

因为我丢失了计数值13。

您认为只有一种方法可以在一个查询中执行此操作吗?

1 个答案:

答案 0 :(得分:3)

您可以在投影中使用$ cond来设置null而不是0,因为在使用平均值时不会考虑null。

db.avg.aggregate([
   {$project:{
       _id:1,
       valueToSum:1,
       stringToGroupByOn:1,
       valueToAvg:{$cond: 
             { if: { $eq: [ "$valueToAvg", 0 ] }, 
                   then: null, 
                   else: "$valueToAvg" }}           
       }},
    { 
        $group : {
            _id : '$stringToGroupByOn',
            avg : { $avg :  '$valueToAvg' }, 
            count : { $sum : '$valueToSum' }
        }
    }
  

输出:

{
    "_id" : "foo",
    "avg" : 42.0,
    "count" : 34.0
}