3

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

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

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

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

是否可以在不发出其他查询且不离开聚合管道的情况下确定结果选择中每一行发生的情况?

更新

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

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

一些文档可能有 fieldB 但没有 fieldC,反之亦然。

4

2 回答 2

2

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

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

这样,您将仅获得已fieldB设置的文档。

更新

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

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

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

于 2013-11-04T12:54:39.657 回答
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 或缺失。

希望这可以帮助,

布鲁斯

于 2013-11-04T15:09:23.433 回答