【问题标题】:MongoDB: how to aggregate array field that may be missingMongoDB:如何聚合可能丢失的数组字段
【发布时间】:2017-06-26 16:50:46
【问题描述】:

当数组字段可能完全丢失时(如第 10 个月的情况),我如何让 MongoDB 计算数组值的总和?

例如:

> db.month.save({MonthNum: 10, 
...              NumWeekdays: 23});
> db.month.save({MonthNum: 11, 
...              NumWeekdays: 21,
...              Holidays: [ {Description: "Thanksgiving",   NumDays: 2} ] });
> db.month.save({MonthNum: 12, 
...              NumWeekdays: 22,
...              Holidays: [ {Description: "Christmas",      NumDays: 6},
...                          {Description: "New Year's Eve", NumDays: 1} ] });
> db.month.aggregate( { $unwind: "$Holidays" }, 
...                   { $group: { _id: "$MonthNum", 
...                               total: { $sum: "$Holidays.NumDays" } } });
{
    "result" : [
        {
            "_id" : 12,
            "total" : 7
        },
        {
            "_id" : 11,
            "total" : 2
        }
    ],
    "ok" : 1
}

如何让第 10 个月显示在上述结果中(将“总计”显示为 0)?

奖励:我如何让上面显示可用的工作日(NumWeekdays 减去假期的总和)?

我已经尝试 $project 首先将数据转换为规范格式,但到目前为止没有成功...谢谢!

【问题讨论】:

    标签: mongodb aggregation-framework


    【解决方案1】:

    $unwind 没有通过MonthNum 10 传递您的文档,因为您的Holidays 数组在该文档上是空的(请参阅$unwind docs 底部的注释)。 假设 Holidays 始终是包含至少一个项目的数组或文档中完全不存在,您可以使用 $project 内部的 $ifNull operator 添加一个“假日”文档有 NumDays = 0 到您的 Holidays 为空:

    db.month.aggregate([
        // Make "Holidays" = [{NumDays:0}] if "Holidays" is null for this document (i.e. absent)
        {$project:{NumWeekDays:1, MonthNum:1, Holidays:{$ifNull:["$Holidays", [{"NumDays":0}]]}}},
        // Now you can unwind + group as normal
        {$unwind:"$Holidays"},
        {$group:{_id:"$MonthNum", NumWeekDays:{$first:"$NumWeekDays"}, "total":{$sum:"$Holidays.NumDays"}}},
        // This should take care of "available weekdays"
        {$project:{total:1, available:{$subtract:["$NumWeekDays", "$total"]}}}
    ]);
    

    请注意,如果您的某些文档Holidays 是一个空数组,则$ifNull 将不起作用;它必须完全不存在。

    【讨论】:

    • 如果它是一个空数组,您可以通过使用 $cond 对其进行测试并将其替换为您正在使用的相同默认值来满足它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-02-27
    • 1970-01-01
    • 1970-01-01
    • 2019-05-10
    • 2020-10-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多