【问题标题】:In mongo aggregate pipeline, how to distinguish null and 0 when using a sum operator在mongo聚合管道中,使用求和运算符时如何区分null和0
【发布时间】:2017-06-23 12:10:22
【问题描述】:

我正在使用 mongo 3.0.4 通过键对数据进行分组。假设我们有一些 mongo 文档,比如

{'a': 1, 'b': 2, 'name': 'leo'}
{'a': 1, 'b': 2, 'name': 'leo'}
{'a': 2, 'b': 2, 'c': 0, 'name': 'amy'}
{'a': 2, 'b': 2, 'c': 0, 'name': 'amy'}

我尝试通过键“名称”聚合并使用下面的代码对所有 a、b、c 字段求和

[
{
    '$group': {
        '_id': '$name',
        'a': {
            '$sum': '$a'
        },
        'b': {
            '$sum': '$b'
        },
        'c': {
            '$sum': '$c'
        }
    }
}
]

得到这样的结果

[
{
    '_id': 'leo',
    'a': 2,
    'b': 4,
    'c': 0
},
{
    '_id': 'amy',
    'a': 4,
    'b': 4,
    'c': 0
}
]

问题是 leo 组中的“c”字段也是 0,我希望它为空。 预期的结果应该是

[
{
    '_id': 'leo',
    'a': 2,
    'b': 4,
    'c': null
},
{
    '_id': 'amy',
    'a': 4,
    'b': 4,
    'c': 0
}
]

[
{
    '_id': 'leo',
    'a': 2,
    'b': 4
},
{
    '_id': 'amy',
    'a': 4,
    'b': 4,
    'c': 0
}
]

我知道$sum 运算符将无数字字段视为 0,那么有什么方法可以做到这一点吗?使用 sum 运算符时如何区分 null 和 0?

【问题讨论】:

  • 我猜你无法在单个查询中实现这一点。您必须将查询分成两部分。
  • 有没有机会在一个管道中实现?比如使用匹配,项目...

标签: mongodb aggregation-framework


【解决方案1】:

我试过了,可能对你有帮助

    db.gg.aggregate([{
            '$group': {
                '_id': '$name',
                'a': {
                    '$sum': '$a'
                },
                'b': {
                    '$sum': '$b'
                },
                'c': {
                    '$sum': '$c'
                },
                cdata: {
                    $push: {
                        c: "$c"
                    }
                }
            }
        },

        {
            $project: {
                _id: 1,
                a: 1,
                b: 1,
                c: {
                    $cond: [{
                        $eq: [{
                            $setIsSubset: [
                                [{}], "$cdata"
                            ]
                        }, true]
                    }, null, "$c"]
                }
            }
        }
    ])

输出:

     { "_id" : "amy", "a" : 4, "b" : 4, "c" : 0 }
     { "_id" : "leo", "a" : 2, "b" : 4, "c" : null }

【讨论】:

  • 感谢帮助,$push在这种情况下很有用,唯一的问题是文件可能很大,我担心使用$push会影响性能。无论如何这是个好主意,非常感谢
【解决方案2】:

终于找到了

[
{
    '$project': {
        'a': 1,
        'b': 1,
        'c': 1,
        'c_count': {
            '$cond': [
                {'$gt': ['$c', null]},
                1,
                0
            ]
        }
    }
},
{
    '$group': {
        '_id': '$name',
        'a': {
            '$sum': '$a'
        },
        'b': {
            '$sum': '$b',
        },
        'c': {
            '$sum': '$c'
        },
        'c_count': {
            '$sum': '$c_count'
        }
    }
},
{
    '$project': {
        'a': 1,
        'b': 1,
        'c': {
            '$cond': [
                '$c_count',
                '$c',
                null
            ]
        }
    }
}
]

第一个项目可以计算出包含字段 c 的文档计数, 因为bson-sort-order 中的空字段很低。之后,就可以在下面的管道中对 null 和 0 进行数字化了

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-07-10
    • 1970-01-01
    • 2021-09-17
    • 1970-01-01
    • 2016-04-26
    • 1970-01-01
    • 2018-10-15
    相关资源
    最近更新 更多