如何确定平均值是0还是null?

时间:2013-11-04 11:12:52

标签: mongodb aggregation-framework

我有一个Mongo数据库,我在其中运行一些聚合查询。这是我想要运行的简化查询:

db.coll.aggregate([
 { $group: { 
   _id: 'fieldA', 
   fieldB: { $avg: '$fieldB' } 
 } },
])

它按fieldA对数据进行分组,并计算fieldB的平均值。无论如何,结果集中的某些行为fieldB的值为0。这可能有两个原因:

  1. 平均值IS 0。
  2. 组中的所有文档都没有fieldB(或者为null值);在这种情况下,Mongo的行为是返回0。
  3. 是否有可能确定在结果选择中每行发生了哪种情况而不发出其他查询且没有离开聚合管道?

    更新

    我无法过滤掉非空字段,因为我正在为少数字段进行聚合,例如:

    db.coll.aggregate([
     { $group: { 
       _id: 'fieldA', 
       fieldB: { $avg: '$fieldB' },
       fieldC: { $avg: '$fieldC' } 
     } },
    ])
    

    某些文档可能包含fieldB但不包含fieldC,反之亦然。

2 个答案:

答案 0 :(得分:2)

您可以在$match操作之前使用$group过滤数据。

db.coll.aggregate([
 { $match: { fieldB : {$ne : null }}}},
 { $group: { 
   _id: 'fieldA', 
   fieldB: { $avg: '$fieldB' } 
 } },
])

这样您只会获得fieldB设置的文档。

<强>更新

您无法使用$avg,但您可以使用$min运算符查看所有值是否为NULL

db.coll.aggregate([
 { $group: { 
   _id: 'fieldA', 
   fieldB: { $avg: '$fieldB' } , 
   fieldBAllNullOrMin: { $min: '$fieldB' } 
 } },
])

如果所有 null $min运算符将返回null,否则返回min。值(但仅限2.4+版本的MongoDB)。

答案 1 :(得分:2)

您可以使用$ max(或$ min)运算符来确定是否全部 组中fieldB的实例为null或缺失,如$ max(或 $ min)运算符在这种情况下返回null。考虑到这种聚合 管道

c.aggregate([
    {$group: {
        _id: '$fieldA',
        avg: {$avg: '$fieldB'},
        max: {$max: '$fieldB'},
    }}
])

这些文件:

c.insert({fieldA: 1, fieldB: 3})
c.insert({fieldA: 1, fieldB: -3})

结果是:

{"_id": 1, "avg": 0, "max": 3}

而对于这些文件:

c.insert({fieldA: 1})
c.insert({fieldA: 1})

结果是:

{"_id": 1, "avg": 0, "max": null}

max字段的null值告诉您fieldB为null或 在小组的所有文件中都没有。

希望这有帮助,

布鲁斯