1

当数组字段可能完全丢失时(如第 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 首先将数据转换为规范格式,但到目前为止没有成功......谢谢!

4

1 回答 1

0

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

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"]}}}
]);

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

于 2013-10-29T23:21:20.427 回答