Mongoose汇总$ sum返回零

时间:2015-11-16 14:28:47

标签: node.js mongodb mongoose aggregation-framework

我有一个像这样的聚合函数:

var match = {};
match["products.totalprice"] = {$exists:true};

var project = {};
    project["_id"] = 0
    project["products.totalprice"] = 1;
    project["line"] = "$products.closedate";

ThisCollection.aggregate([
    {$match: match},
    {$project: project},
    {$group: {
        _id: "$line",
        total: {$sum: {$ifNull: ["$products.totalprice", 0]}}
    }}

], function(err, docs){
    console.log(docs);
});

我的架构本质上是一个名称和_id字段,带有嵌套的产品数组,包括totalprice,closedate和其他一些字段:

db.data.save({name:"a",products:{totalprice:1,closedate:1,...}})
db.data.save({name:"b",products:{totalprice:2,closedate:2,...}})

和Schemas看起来像:

var Products = new Schema({
    totalprice: Number,
    closedate: Date,
    otherRandomFields: ...
}) 

var ThisCollection = new Schema({
    name: String, 
    products:[Products]
});

docs返回我期望看到的日期对象,但总计为0.

我正在检查$exists$ifNull正如我在某处看到的那样建议(但现在似乎无法找到)。我还确认products.totalprice在我的架构中属于Number类型。

有什么事情对任何人都不正确吗?

修改

运行此功能的实际(部分)输出:

0: {_id: ["2014-01-01T05:00:00.000Z"], total: 0}
1: {_id: ["2014-01-31T05:00:00.000Z"], total: 0}
2: {_id: ["2014-02-01T05:00:00.000Z"], total: 0}

_id返回一个数组有点奇怪吗?

更多信息

认为这可能是$sum的一个问题,所以尝试了一些其他方法,例如$first$push - 这里是$push的输出:< / p>

0: {_id: "2014-01-01T05:00:00.000Z", total: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}
1: {_id: "2014-01-31T05:00:00.000Z", total: [0, 0, 0]}
2: {_id: "2014-02-01T05:00:00.000Z", total: [0, 0, 0, 0, 0, 0, 0]}

1 个答案:

答案 0 :(得分:1)

尝试使用以下聚合管道,它会提取 $year $month $dayOfMonth 从您的日期开始,然后按键使用这些组。此外,检查字段是否存在并为其赋值的逻辑理想情况下应在 $project 管道中完成,因为这使您可以轻松调试管道操作并且代码可读:< / p>

var match = {};
match["products.totalprice"] = {$exists:true};

var project = {};
    project["_id"] = 0;        
    project["line"] = {
        "year": { "$year": "$products.closedate" },
        "month": { "$month": "$products.closedate" },
        "day": { "$dayOfMonth": "$products.closedate" }
    };
    project["total"] = {
        "$ifNull": [ "$products.totalprice", 0 ]
    }

ThisCollection.aggregate([
    {$unwind: "$products"},
    {$match: match},
    {$project: project},
    {$group: {
        _id: "$line",
        total: { $sum: "$total" }
    }}

], function(err, docs){
    console.log(docs);
});

$unwind属性,否则它会尝试将$total返回的数组加在一起。