Mongo Aggregation给出了荒谬的结果

时间:2014-06-21 18:37:42

标签: mongodb aggregation-framework

我正在按照mongo查询运行:

db.docs.aggregate([
    {'$group': {
        '_id': 1,        
        'total_neg_sent_count': {'$sum': {'$cond': [{'$lt': ['$s', 0]}, 1, 0]}}
    }}
])

关于以下文件:

/* 0 */
{
    "_id" : ObjectId("53a5c8f13f35b7fc1280c60a"),
    "rT" : 5
}

/* 1 */
{
    "_id" : ObjectId("53a5c8f13f35b7fc1280c60b"),
    "abc" : 1
}

/* 2 */
{
    "_id" : ObjectId("53a5c8f13f35b7fc1280c60c"),
    "rT" : 0
}

答案是出乎意料的:

{
    "result" : [ 
        {
            "_id" : 1,
            "total_neg_sent_count" : 3
        }
    ],
    "ok" : 1
}

我不知道mongo在这做什么。它应该返回'0'作为计数,所有文件中都缺少's'。

1 个答案:

答案 0 :(得分:0)

这不符合您的想法,因为缺少的字段实际评估为null,而0被视为“小于”此值:

db.docs.aggregate([{ "$project": { "s": { "$ifNull": [ "$s", null ] }} }])

将评估显示为null,然后考虑这一点,逻辑的原始部分:

db.docs.aggregate([{ "$project": { "s": { "$lt": [ "$s", 0 ] }} }])

会显示此条件的计算结果为true,因此会返回$cond语句中的第一个值。因此,为了考虑缺失字段的值,您将使用$ifNull,如前所示:

db.docs.aggregate([
    { "$group": {
        "_id": 1,        
        "total_neg_sent_count": {
            "$sum": {
                "$cond": [ {"$lt": [ {"$ifNull": [ "$s", 0 ] }, 0] }, 1, 0 ]
            }
        }
    }}
])

当文档中缺少该字段时,$ifNull返回的值将为0,当然不是$lt 0,并且会返回您的预期值。