我有一个Mongo数据库,我在其中运行一些聚合查询。这是我想运行的简化查询:
db.coll.aggregate([
{ $group: {
_id: 'fieldA',
fieldB: { $avg: '$fieldB' }
} },
])
它按字段A对数据进行分组并计算字段B的平均值。无论如何,结果集中的某些行的字段B值为0。这可能有2个原因:
是否可以确定结果选择中的每一行发生了哪种场景,而无需发出其他查询并且无需离开聚合管道?
更新
我无法过滤掉非空字段,因为我正在为少数字段进行聚合,如下所示:
db.coll.aggregate([
{ $group: {
_id: 'fieldA',
fieldB: { $avg: '$fieldB' },
fieldC: { $avg: '$fieldC' }
} },
])
一些文档可能有field dB但没有field dC,反之亦然。
您可以在$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为空或缺失。
希望这有帮助,
布鲁斯