提问者:小点点

如何确定平均值是否为0 vs null?


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

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

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

  1. 平均值为0。
  2. 组中的所有文档都没有field dB(或具有null作为值);在这种情况下,Mongo行为是返回0。

是否可以确定结果选择中的每一行发生了哪种场景,而无需发出其他查询并且无需离开聚合管道?

更新

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

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

一些文档可能有field dB但没有field dC,反之亦然。


共2个答案

匿名用户

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

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

这样您将只获得设置了field dB的文档。

更新

您不能以这种方式使用$avg,但您可以使用$min运算符找出是否所有值都为NULL

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

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

匿名用户

您可以使用$max(或$min)运算符来确定组中的所有field dB实例是否为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字段的空值告诉您该组中的所有文档中的field dB为空或缺失。

希望这有帮助,

布鲁斯