我每周都会从服务中接收数据,并将其放入集合中。数据有一个amount,projectNo和dataDate时间戳。使用聚合框架,我按照projectNo和dataDate:
对数量和组进行求和db.collection.aggregate([
{$project: {projectNo: 1, bdgtAppd: 1, dataDate: 1}},
{$group: {_id: {
projectNo: "$projectNo",
dataDate: "$dataDate"
},
amount: {$sum: "$bdgtAppd"}}
},
{$project: {_id:0,
projectNo:"$_id.projectNo",
dataDate:"$_id.dataDate",
amount:"$amount"
}
},
{$sort: {projectNo:1,dataDate:1}}
])
产生这个:
[{
"amount" : 7887,
"projectNo" : "5544A",
"dataDate" : "2015-01-02T08:00:00.000Z"
}, {
"amount" : 137947,
"projectNo" : "5544A",
"dataDate" : "2015-01-16T08:00:00.000Z"
}, {
"amount" : 137947,
"projectNo" : "5544A",
"dataDate" : "2015-01-23T08:00:00.000Z"
}, {
"amount" : 137947,
"projectNo" : "5544A",
"dataDate" : "2015-01-30T08:00:00.000Z"
}, {
"amount" : 130060,
"projectNo" : "5544A",
"dataDate" : "2015-02-06T08:00:00.000Z"
}, {
"amount" : 130060,
"projectNo" : "5544A",
"dataDate" : "2015-02-13T08:00:00.000Z"
}, {
"amount" : 130060,
"projectNo" : "5544A",
"dataDate" : "2015-02-20T08:00:00.000Z"
}]
我现在需要做的是将返回的数据限制在该月的最后一个日期:
[{
"amount" : 137947,
"projectNo" : "5544A",
"dataDate" : "2015-01-30T08:00:00.000Z"
}, {
"amount" : 130060,
"projectNo" : "5544A",
"dataDate" : "2015-02-27T08:00:00.000Z"
}]
编辑:集合中的示例文档:
{
"_id" : ObjectId("5527e724fc53ec16bc5fe57a"),
"projectNo" : "5544G",
"cpfoNo" : "1448R",
"cpfoDate" : ISODate("2014-10-20T07:00:00Z"),
"description" : "INC 6 CO 176 - Booster Pump",
"pcoNo" : "1510",
"approvedAmount" : null,
"days" : null,
"remarks" : null,
"itemNo" : "0005",
"costCode" : "5030.09900.0000.0000",
"itemTitle" : "Painting - Hasson",
"bdgtEst" : 0.0,
"bdgtProp" : 745.0,
"bdgtAprv" : 745.0,
"bdgtAppd" : 745.0,
"dataDate" : ISODate("2014-12-12T08:00:00Z")
}
答案 0 :(得分:1)
不需要初始 $project
管道阶段,只需从 $group
步骤开始,以下管道阶段将产生期望的结果:
db.collection.aggregate([
{
"$group": {
"_id": {
"projectNo": "$projectNo",
"dataDate": "$dataDate"
},
"amount": {"$sum": "$bdgtAppd"}
}
},
{
"$project": {
"_id": 0,
"projectNo": "$_id.projectNo",
"dataDate": "$_id.dataDate",
"amount": 1
}
},
{
"$group": {
"_id": "$projectNo",
"dataDate": {"$first" : "$dataDate"},
"amount": {"$first" : "$amount"}
}
},
{
"$project": {
"_id": 0,
"projectNo": "$_id",
"dataDate": 1,
"amount": 1
}
}
]);
使用以下示例文档(仅包括相关字段作为最小测试用例):
db.collection.insert([
/* 0 */
{
"projectNo" : "5544A",
"bdgtAppd" : 3,
"dataDate" : ISODate("2015-01-02T08:00:00.000Z")
},
/* 1 */
{
"projectNo" : "5544A",
"bdgtAppd" : 7,
"dataDate" : ISODate("2015-01-28T08:00:00.000Z")
},
/* 2 */
{
"projectNo" : "5544A",
"bdgtAppd" : 5,
"dataDate" : ISODate("2015-01-28T08:00:00.000Z")
},
/* 3 */
{
"projectNo" : "5544B",
"bdgtAppd" : 15,
"dataDate" : ISODate("2015-02-13T08:00:00.000Z")
},
/* 4 */
{
"projectNo" : "5544G",
"bdgtAppd" : 10,
"dataDate" : ISODate("2015-02-27T08:00:00.000Z")
},
/* 5 */
{
"projectNo" : "5544G",
"bdgtAppd" : 25,
"dataDate" : ISODate("2015-02-27T08:00:00.000Z")
},
]);
以上聚合产生:
/* 0 */
{
"result" : [
{
"dataDate" : ISODate("2015-01-28T08:00:00.000Z"),
"amount" : 12,
"projectNo" : "5544A"
},
{
"dataDate" : ISODate("2015-02-13T08:00:00.000Z"),
"amount" : 15,
"projectNo" : "5544B"
},
{
"dataDate" : ISODate("2015-02-27T08:00:00.000Z"),
"amount" : 35,
"projectNo" : "5544G"
}
],
"ok" : 1
}
答案 1 :(得分:1)
感谢@chidrian让我开始。这是适合我的解决方案。可能是投射月份和年份键的额外步骤,但它可以工作。
{
"$group": {
"_id": {
"projectNo": "$projectNo",
"dataDate": "$dataDate"
},
"sum": "$bdgtAppd"
}
}
}, {
"$project": {
"_id": 0,
"projectNo": "$_id.projectNo",
"dataDate": "$_id.dataDate",
"amount": 1
}
}, {
"$project": {
"_id": 0,
"projectNo": "$projectNo",
"amount": 1,
"dataDate": 1,
"month": {
$month: "$dataDate"
},
"year": {
"$year": "$dataDate"
}
}
}, {
"$sort": {
projectNo: 1,
dataDate: 1
}
}, {
"$group": {
"_id": {
"projectNo": "$projectNo",
"month": "$month",
"year": "$year"
},
"dataDate": {
"$last": "$dataDate"
},
"amount": {
"$last": "$amount"
}
}
}, {
"$sort": {
projectNo: 1,
dataDate: 1
}
}, {
"$project": {
"_id": 0,
"projectNo": "$_id.projectNo",
"dataDate": 1,
"amount": 1
}
}