【问题标题】:how to convert timestamp to ISO date in mongodb aggregate如何在mongodb聚合中将时间戳转换为ISO日期
【发布时间】:2015-03-25 17:19:45
【问题描述】:

我正在使用 node.js mongodb 客户端。 我在一个集合中有一个时间戳值,现在我想使用聚合将时间戳转换为 IOSDate,所以我可以很容易地比较它。但我不知道该怎么做。

   var db = game.getDB();
    var coll = db.collection("LoginRecord");
    coll.aggregate([
        {
            $project: {
                "PT" : 1,
                "PID" : 1,
                "regDate" : new Date("$createTime"), //#####createTime is a timestamp, I want to convert it to IOSDate
                "loginDay" : { $dayOfYear : "$_serverDate"}
            }
        },
        {
            $group : {
                "_id" : "$loginDay",
                "logUsers" : { $addToSet: "$PID"}
            }
        },
        {
            $unwind : "$logUsers"
        },
        {
            "$group" : {
                "_id" : "$_id",
                "logCount" : { $sum: 1}
            }
        }
    ], function(err, res) {
        logger.info("aggregate res " + JSON.stringify(res));
    });

【问题讨论】:

  • 你不能那样做。您正在使用的 JavaScript 函数在管道内容发送到服务器的“外部”和“之前”进行评估。在管道执行期间,您不能在元素上使用任意代码。您将需要使用时间戳值来确定“dayOfYear”(非常复杂,我“相当”确定聚合框架没有必要的数学运算符来处理它)。或者以其他方式将您的集合转换为使用 Date 类型。但是你不能在管道执行中使用这种方式。
  • 如果我的 mongodb 客户端是 c++,我如何制作一个有时间值的 json 值,当 json 发送到 mongodb 时,日期值会自动保存为 ISODate 值?我怎样才能完成它?
  • 驱动程序库将有一个日期对象类型。如果您不确定如何使用它,请发布另一个问题。根据我的解释,您在这里尝试做的事情是不可能的。
  • 好的,非常感谢!

标签: mongodb mongodb-query aggregation-framework


【解决方案1】:

Mongodb 4.0 引入了 $toDate 聚合,它只是将时间戳转换为 ISO 日期

db.collection.aggregate([
  { "$project": {
    "regDate": { "$toDate": "$createTime" }
  }}
])

你可以试试here

【讨论】:

    【解决方案2】:

    如参考convert milliseconds to date in mongodb aggregation pipeline for group by?

    您可以按如下方式将毫秒(时间戳)转换为日期对象:

    "regDate": {
       $add: [ new Date(0), "$createTime" ]
    }
    

    【讨论】:

    • 时间戳是低和高的 64 位秒数。在 4.0 之前,$add 不允许使用时间戳数据。
    【解决方案3】:

    不幸的是,MongoDB 没有提供简单的方法来做到这一点。

    我解决它的方法是使用map 函数将 date 字段注入结果中。

    首先,设置一个日期转换函数,如下所示:

    function toDateStr(ts) {
        let dataF = new Date();   dataF.setTime(ts);
        let strDataF = dataF.toLocaleString();
        return strDataF;
    }
    

    然后,在您的聚合中,只需在每个文档上调用此函数并插入一个新的日期字段。像这样:

    db.Collection.aggregate([
         {
           $project: {
                timestamp: 1
              }
          },
          {
              $match: { /* something */
              }
          }
       ]
    ).map(function(doc) {
        doc['date'] = toDateStr(doc.timestamp);
        return doc
    })
    

    【讨论】:

      【解决方案4】:

      在使用聚合框架之前,只需查询集合并将文档更新为 ISODate 日期格式。 Mongodb 时间戳对象仅供内部使用。因此,您应该将其永久切换为 ISODate 类型。 链接到warning.

      【讨论】:

        猜你喜欢
        • 2019-09-15
        • 1970-01-01
        • 2019-05-09
        • 2021-10-23
        • 1970-01-01
        • 2011-04-16
        • 2018-12-25
        • 2019-01-18
        相关资源
        最近更新 更多