va5*_*5ja 4 mongodb unix-timestamp isodate mongodb-query aggregation-framework
我正在寻找这个,但我找不到任何有用的解决我的情况.我想要的是在聚合期间以几秒为单位获取MongoDB ISODate的unix时间戳.问题是我可以从ISODate中获取时间戳,但它是以毫秒为单位.所以我需要减少那些毫秒.我试过的是:
> db.data.aggregate([
{$match: {dt:2}},
{$project: {timestamp: {$concat: [{$substr: ["$md", 0, -1]}, '01', {$substr: ["$id", 0, -1]}]}}}
])
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,我正在尝试从'md'var中获取时间戳,并将此时间戳与'01'和'id'数字连接起来.上面的代码给出:
{
"_id" : ObjectId("52f8fc693890fc270d8b456b"),
"timestamp" : "2014-02-10T16:20:56011141"
}
Run Code Online (Sandbox Code Playgroud)
然后我改进了命令:
> db.data.aggregate([
{$match: {dt:2}},
{$project: {timestamp: {$concat: [{$substr: [{$subtract: ["$md", new Date('1970-01-01')]}, 0, -1]}, '01', {$substr: ["$id", 0, -1]}]}}}
])
Run Code Online (Sandbox Code Playgroud)
现在我得到:
{
"_id" : ObjectId("52f8fc693890fc270d8b456b"),
"timestamp" : "1392049256000011141"
}
Run Code Online (Sandbox Code Playgroud)
我真正需要的是1392049256011141所以没有3额外的000.我尝试了$减法:
> db.data.aggregate([
{$match: {dt:2}},
{$project: {timestamp: {$concat: [{$substr: [{$divide: [{$subtract: ["$md", new Date('1970-01-01')]}, 1000]}, 0, -1]}, '01', {$substr: ["$id", 0, -1]}]}}}
])
Run Code Online (Sandbox Code Playgroud)
我得到的是:
{
"_id" : ObjectId("52f8fc693890fc270d8b456b"),
"timestamp" : "1.39205e+009011141"
}
Run Code Online (Sandbox Code Playgroud)
不完全是我对命令的期望.不幸的是,$ substr运算符不允许负长度.有没有人有其他解决方案?
我不确定为什么你认为你需要以秒为单位而不是毫秒的值,因为通常两种形式都是有效的,并且在大多数语言实现中,毫秒实际上是首选的.但一般来说,尝试将其强制转换为字符串是错误的解决方法,通常你只是做数学:
db.data.aggregate([
{ "$project": {
"timestamp": {
"$subtract": [
{ "$divide": [
{ "$subtract": [ "$md", new Date("1970-01-01") ] },
1000
]},
{ "$mod": [
{ "$divide": [
{ "$subtract": [ "$md", new Date("1970-01-01") ] },
1000
]},
1
]}
]
}
}}
])
Run Code Online (Sandbox Code Playgroud)
这会以秒为单位返回一个纪元时间戳.基本上从一个BSON日期对象从另一个BSON日期对象中减去时得出,结果是以毫秒为单位的时间间隔.使用"1970-01-01"的初始纪元日期导致基本上从当前日期值中提取毫秒值.的$divide操作者基本上起飞的毫秒部分和$mod确实模来实现舍入.
实际上,您最好使用母语为您的应用程序进行工作,因为所有BSON日期都将作为本机"日期/日期时间"类型返回,您可以在其中提取时间戳值.考虑shell中的JavaScript基础知识:
var date = new Date()
( date.valueOf() / 1000 ) - ( ( date.valueOf() / 1000 ) % 1 )
Run Code Online (Sandbox Code Playgroud)
通常使用聚合,您希望对时间戳值执行此类"数学运算",以便在诸如一天等时间段内聚合值.聚合框架可以使用日期运算符,但您也可以使用日期数学方式:
db.data.aggregate([
{ "$group": {
"_id": {
"$subtract": [
{ "$subtract": [ "$md", new Date("1970-01-01") ] },
{ "$mod": [
{ "$subtract": [ "$md", new Date("1970-01-01") ] },
1000 * 60 * 60 * 24
]}
]
},
"count": { "$sum": 1 }
}}
])
Run Code Online (Sandbox Code Playgroud)
这种形式更典型的是将时间戳舍入到一天,并在这些间隔内汇总结果.
因此,仅仅提取时间戳的聚合框架的目的似乎并不是最佳用法,或者实际上不需要将其转换为秒而不是毫秒.在您的应用程序代码中我认为您应该这样做,除非您当然希望结果的时间间隔可以应用所示的日期数学.
方法在那里,但除非你实际上是聚合,否则这将是你的应用程序的最差性能选项.代替转换代码.
| 归档时间: |
|
| 查看次数: |
8436 次 |
| 最近记录: |