mongodb中按时间戳日期聚合数据



我以unix时间戳格式存储项目的创建时间。现在我想把它聚合起来,例如,根据年份。但是,不幸的是,它不起作用,应该。。。

以下是源数据:

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.如果我在Date函数中指出确切时间:

db.invoice.aggregate(
{$match: {id: '01f96c0d4254cdd69692d97c3909fb6dff75066b'}}, 
{$group: 
    {_id: {  year: {$year: new Date(1397661552000)}  }, 
    total: {$sum: '$amount'}}
}
)

它似乎工作和输出2014年

$year运算符和所有日期聚合运算符完全按照设计工作。但这里的问题是,您的"created"实际上不是BSON日期类型,实际上只是一个表示epoch时间戳的数字。

所以,如果你真的有一个BSON日期,它在外壳中看起来是这样的:

ISODate("2014-04-18T03:54:40.023Z")

然后操作员将工作。但在您的情况下,它们没有,这是一个遗憾,因为BSON日期类型实际上只是内部的epoch时间戳,因此不会占用任何额外的存储空间。

但由于你的"时间戳"只是数字,你所需要做的就是做一点"日期数学",以获得你想要的年份界限:

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转换器的网站上检查结果中的epoch日期,或者只将其输入到date对象中。

相关内容

  • 没有找到相关文章

最新更新