首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >将数据从毫秒转换为ISODate对象

将数据从毫秒转换为ISODate对象
EN

Stack Overflow用户
提问于 2014-03-27 20:14:24
回答 5查看 15.7K关注 0票数 22

我试图按小时聚合MongoDB集合中的记录,并需要将存储为时间戳(毫秒)的日期转换为ISODate,以便使用聚合框架的内置日期运算符($hour、$month等)。

记录存储为

代码语言:javascript
运行
复制
{ 
"data" : { "UserId" : "abc", "ProjId" : "xyz"}, 
"time" : NumberLong("1395140780706"),
"_id" : ObjectId("532828ac338ed9c33aa8eca7") 
} 

我试图使用以下类型的聚合查询:

代码语言:javascript
运行
复制
db.events.aggregate(
    { 
       $match : { 
         "time" : { $gte : 1395186209804, $lte : 1395192902825 } 
       } 
    }, 
    { 
       $project : {
         _id : "$_id", 
         dt : {$concat : (Date("$time")).toString()} // need to project as ISODate
       } 
    },
    // process records further in $project or $group clause
)

它产生表格的结果:

代码语言:javascript
运行
复制
{
    "result" : [
        { 
            "_id" : ObjectId("5328da21fd207d9c3567d3ec"), 
            "dt" : "Fri Mar 21 2014 17:35:46 GMT-0400 (EDT)" 
        }, 
        { 
            "_id" : ObjectId("5328da21fd207d9c3567d3ed"), 
            "dt" : "Fri Mar 21 2014 17:35:46 GMT-0400 (EDT)" 
        }, 
            ... 
} 

我想从日期提取小时、日、月和年,但是由于时间是以字符串形式预测的,所以我无法使用聚合框架的内置日期运算符($hour等)。

如何将时间从毫秒转换为ISO日期,以便执行以下操作:

代码语言:javascript
运行
复制
db.events.aggregate(
    {
        $match : { 
            "time" : { $gte : 1395186209804, $lte : 1395192902825 } 
        }
    },
    {
        $project : {
            _id : "$_id",
            dt : <ISO date from "$time">
        }
    },
    { 
        $project : {
            _id : "$_id",
            date : { 
                hour : {$hour : "$dt"} 
            }
        }
    }
)
EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2014-03-28 02:32:41

我想是没有办法的。因为聚合框架是用本机代码编写的。不使用V8引擎。因此,JavaScript的所有功能都不能在框架内工作(这也是为什么聚合框架运行得更快的原因)。

Map/Reduce是解决这个问题的一种方法,但是聚合框架无疑获得了更好的性能。

关于地图/降低性能,请阅读this thread

另一种解决方法是从聚合框架获得“原始”结果,将其放入JSON数组中。然后通过运行JavaScript来完成转换。有点像:

代码语言:javascript
运行
复制
var results = db.events.aggregate(...);
reasult.forEach(function(data) {
    data.date = new Date(data.dateInMillionSeconds);
    // date is now stored in the "date" property
}
票数 7
EN

Stack Overflow用户

发布于 2015-01-07 21:28:46

实际上,诀窍是使用类似于以下的语法将毫秒时间添加到零毫秒日期()对象:

代码语言:javascript
运行
复制
dt : {$add: [new Date(0), "$time"]}

我从上面修改了您的聚合,以生成结果:

代码语言:javascript
运行
复制
db.events.aggregate(
    {
        $project : {
            _id : "$_id",
            dt : {$add: [new Date(0), "$time"]}
        }
    },
    { 
        $project : {
            _id : "$_id",
            date : { 
                hour : {$hour : "$dt"} 
            }
        }
    }
);

结果是(只输入一个样本数据):

代码语言:javascript
运行
复制
{
  "result": [
    {
      "_id": ObjectId("532828ac338ed9c33aa8eca7"),
      "date": {
        "hour": 11
      }
    }
  ],
  "ok": 1
}
票数 30
EN

Stack Overflow用户

发布于 2016-01-08 16:23:45

要返回有效的BSON日期,只需使用$add运算符的一个小日期“数学”即可。需要将new Date(0)添加到时间戳中。new Date(0)表示自Unix时代(1970年1月1日)以来的毫秒数,是new Date("1970-01-01")的缩写。

代码语言:javascript
运行
复制
db.events.aggregate([
    { "$match": { "time": { "$gte" : 1395136209804, "$lte" : 1395192902825 } } },
    { "$project": { 
        "hour": { "$hour": { "$add": [ new Date(0), "$time" ] } }, 
        "day": { "$dayOfMonth":  { "$add": [ new Date(0), "$time" ] } },
        "month": { "$month": { "$add": [ new Date(0), "$time" ] } },
        "year": { "$year":  { "$add": [ new Date(0), "$time" ] } } 
    }} 
])

产生的结果:

代码语言:javascript
运行
复制
{
    "_id" : ObjectId("532828ac338ed9c33aa8eca7"),
    "hour" : 11,
    "day" : 18,
    "month" : 3,
    "year" : 2014
}
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22698265

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档