我有一个像这样的聚合函数:
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]}
答案 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
返回的数组加在一起。