MongoDB聚合包括丢失的文档

JAC*_*703 1 mongodb mongodb-query aggregation-framework

我有一些文件存储在MongoDB中,类似于以下内容:

{
    "id": "0001",
    "name": "Joe",
    "last_name": "Blogs",
    "results":
        [
            { "id": "5001", "mark": "78" },
            { "id": "5002", "mark": "105" },
            { "id": "5005", "mark": "97" },
        ]
}
Run Code Online (Sandbox Code Playgroud)

有许多类似于上面的条目.我遇到的问题是一些"结果"字段完全丢失,所以有些条目如下所示:

{
    "id": "0001",
    "name": "Joe",
    "last_name": "Blogs"
}
Run Code Online (Sandbox Code Playgroud)

我试图聚合这个以返回"名称","last_name"和平均"标记".我对以下代码表示满意:

db.sites.aggregate( 
 { $project : { name : "$name", last_name : "$last_name", results : "$results" } },
 { $unwind: "$results" },
 { $group : { 
    _id : "$_id", 
    average_mark : { $avg : "$results.mark" }, 
    name : { $last : "$name" },
    last_name : { $last : "$last_name" },
 }
)
Run Code Online (Sandbox Code Playgroud)

但是,它不会返回没有"results"数组的条目.

有没有人知道如何返回缺少的"结果"条目并将平均值设置为零?

干杯,

詹姆士.

Nei*_*unn 6

当聚合框架遇到"空"数组时,结果会$unwind有效地从管道中删除文档,因为它被认为没有结果.此外,如果数组根本不存在,则会产生错误,因为操作员将尝试访问不存在的元素.

因此,如果您不希望从聚合结果中明确"过滤"这些文档,则$ifNull存在运算符.它测试是否存在字段,要么返回该字段,要么返回备用提供的参数.

db.sites.aggregate([
    { "$project": { 
        "name": 1, 
        "last_name": 1,
        "results" : { 
            "$ifNull": [ "$results", [{ "mark": 0 }] ]
        }
    }},
    { "$unwind": "$results" },
    { "$group": { 
        "_id" : "$_id", 
        "average_mark": { "$avg": "$results.mark" }, 
        "name": { "$last": "$name" },
        "last_name": { "$last": "$last_name" },
    }}
])
Run Code Online (Sandbox Code Playgroud)

$cond当您真正拥有"空"阵列时,即使组合使用,操作员也可以获得类似的结果:

    "results": { 
        "$cond": [ 
            {"$eq": [ "$results", [] ] },
            [{ "mark": 0 }],
            { "$ifNull": [ "$results", [{ "mark": 0 }] ] }
        ]
    }
Run Code Online (Sandbox Code Playgroud)