我以unix时间戳格式存储项目的创建时间。例如,根据年份,现在我想汇总它。但是,不幸的是,它不起作用,应该...... [/ p>
这是源数据:
db.invoice.find({id: '01f96c0d4254cdd69692d97c3909fb6dff75066b'}, {created: 1, amount: 1})
{ "_id" : ObjectId("534801e8e71709fab334bdd9"), "amount" : 345, "created" : 1397661552 }
但是当我尝试做的时候:
db.invoice.aggregate(
{$match: {id: '01f96c0d4254cdd69692d97c3909fb6dff75066b'}},
{$group:
{_id: { year: {$year: new Date('$created' * 1000)} },
total: {$sum: '$amount'}}
}
)
我得到了
"result" : [
{
"_id" : {
"year" : 292278994
},
"total" : 345
}
],
"ok" : 1
这一年很奇怪......
P.S。如果我在日期函数中指出准确的时间:
db.invoice.aggregate(
{$match: {id: '01f96c0d4254cdd69692d97c3909fb6dff75066b'}},
{$group:
{_id: { year: {$year: new Date(1397661552000)} },
total: {$sum: '$amount'}}
}
)
它似乎工作并输出2014年
答案 0 :(得分:3)
$year
运算符和所有date aggregation运算符完全按照设计工作。但问题在于你的"创造了"实际上并不是BSON date type,实际上只是一个代表纪元时间戳的数字。
所以如果你真的有一个BSON date,它在shell中看起来像这样:
ISODate("2014-04-18T03:54:40.023Z")
然后操作员将工作。但在你的情况下他们没有,这是一种耻辱,因为BSON日期类型实际上只是一个内部的纪元时间戳,因此不会占用任何额外的存储空间。
但是因为你的"时间戳"只是数字,你需要做的只是一个小小的日期数学"为了获得你想要的年份边界:
db.invoice.aggregate([
{ "$group": {
"_id": {
"$add": [
{ "$subtract": [
"$created",
{ "$mod": [
"$created",
31536000 // 60 * 60 * 24 * 365
]}
]},
950400 // correction
]
},
"total": { "$sum": "$amount" }
}}
])
这应该将每个日期值设置为它所属年份的第一天,这样您就可以按年汇总。
"result" : [
{
"_id" : {
"year" : 1388534400
},
"total" : 345
}
],
"ok" : 1
您可以在epoch converter这样的网站上查看结果中的纪元日期,或者只是将其提供给日期对象。