在mongodb聚合管道中将毫秒转换为日期以进行分组?

Posted

技术标签:

【中文标题】在mongodb聚合管道中将毫秒转换为日期以进行分组?【英文标题】:convert milliseconds to date in mongodb aggregation pipeline for group by? 【发布时间】:2015-07-05 16:39:43 【问题描述】:

我必须在 mongodb 聚合 pipiline 中将毫秒转换为日期格式 -

我的查询是 -

db.campaign_wallet.aggregate("$match" : "campaignId" : 1, "txnTime" :  "$gte" : 1429554600000, "$lte" : 1430159400000, "$group" : "_id" : "msisdn" : "$msisdn", "txnTime" : "$txnTime", "count" : "$sum": 1);

在此查询中,如何将 txnTime(以毫秒为单位)转换为管道中的日期?

【问题讨论】:

How to convert miliseconds to date in mongodb aggregation?的可能重复 @AmitDas 请发布查询的实际文本而不是屏幕截图。 @AmitDas 您希望在哪个管道阶段转换该字段?如果您想根据某个日期范围过滤文档,请使用我对此duplicate 的回答中的投影作为第一个管道阶段,然后根据预计日期字段执行$match$group 操作。 In MongoDB $project clause, how can I convert date from milliseconds to ISODate object的可能重复 @AmitDas 帮助我了解您的目标;仅时间戳字段不会给您一个唯一的日期吗?将毫秒转换为日期会产生开销,因为以毫秒为单位的时间戳本质上是一个日期时间值。 【参考方案1】:

我正在尝试获取将 txnTime 字段转换为日期对象背后的逻辑,因为按日期字段或时间戳(以毫秒为单位)进行分组(就像您目前正在做的那样)将产生与它们相同的结果在各自的格式中都是独一无二的!

要将txnTime 字段更改为日期对象,您应该使用此表达式在$group 管道阶段之前包含$project 管道

"txnTime": 
    "$add": [ new Date(0), "$txnTime" ]

这样您就可以在转换/投影的 txnTime 字段上执行 $group 操作:

var convertedTxnTime =  "$add": [new Date(0), "$txnTime"] ;

/*
  If using MongoDB 4.0 and newer, use $toDate 

  var convertedTxnTime =  "$toDate": "$txnTime" ;

  or $convert

  var convertedTxnTime =  "$convert":  "input": "$txnTime", "to": "date"  ;

*/

db.campaign_wallet.aggregate([
     "$match":  
        "campaignId" : 1 , 
        "txnTime" :  
            "$gte" : 1429554600000 , 
            "$lte" : 1430159400000
        
     ,
     "$group" :  
        "_id" : 
            "txnTime": convertedTxnTime,
            "msisdn" : "$msisdn"
        , 
        "msisdnCount" :  "$sum" : 1
     
]);

输出:(基于此question的示例文档)

/* 0 */

    "result" : [ 
        
            "_id" : 
                "txnTime" : ISODate("2015-04-25T18:30:00.000Z"),
                "msisdn" : "91808770101"
            ,
            "msisdnCount" : 1
        , 
        
            "_id" : 
                "txnTime" : ISODate("2015-04-27T05:11:54.796Z"),
                "msisdn" : "9180877010"
            ,
            "msisdnCount" : 1
        , 
        
            "_id" : 
                "txnTime" : ISODate("2015-04-25T18:30:01.111Z"),
                "msisdn" : "91808070101"
            ,
            "msisdnCount" : 1
        , 
        
            "_id" : 
                "txnTime" : ISODate("2015-04-25T18:30:00.000Z"),
                "msisdn" : "91808070101"
            ,
            "msisdnCount" : 2
        , 
        
            "_id" : 
                "txnTime" : ISODate("2015-04-27T05:11:54.796Z"),
                "msisdn" : "9189877000"
            ,
            "msisdnCount" : 1
        , 
        
            "_id" : 
                "txnTime" : ISODate("2015-04-27T05:11:54.796Z"),
                "msisdn" : "9189877667"
            ,
            "msisdnCount" : 1
        
    ],
    "ok" : 1

-- 更新--

要使用 YYYY-MM-DD 格式按日期对文档进行分组,请使用 Date Aggregation Operators

例子:

var convertedTxnTime =  "$add": [new Date(0), "$txnTime"] ;

/*
  If using MongoDB 4.0 and newer, use $toDate 

  var convertedTxnTime =  "$toDate": "$txnTime" ;

  or $convert

  var convertedTxnTime =  "$convert":  "input": "$txnTime", "to": "date"  ;

*/

db.campaign_wallet.aggregate([
     "$match":  
        "campaignId" : 1 , 
        "txnTime" :  
            "$gte" : 1429554600000 , 
            "$lte" : 1430159400000
        
     ,
     "$group" :  
        "_id" : 
            "txnTime_year" :  "$year": convertedTxnTime ,
            "txnTime_month" :  "$month": convertedTxnTime ,
            "txnTime_day" :  "$dayOfMonth": convertedTxnTime ,
            "msisdn": "$msisdn"
        , 
        "msisdnCount" :  "$sum" : 1
     
]);

输出

/* 0 */

    "result" : [ 
        
            "_id" : 
                "txnTime_year" : 2015,
                "txnTime_month" : 4,
                "txnTime_day" : 25,
                "msisdn" : "91808770101"
            ,
            "msisdnCount" : 1
        , 
        
            "_id" : 
                "txnTime_year" : 2015,
                "txnTime_month" : 4,
                "txnTime_day" : 25,
                "msisdn" : "91808070101"
            ,
            "msisdnCount" : 3
        , 
        
            "_id" : 
                "txnTime_year" : 2015,
                "txnTime_month" : 4,
                "txnTime_day" : 27,
                "msisdn" : "9180877010"
            ,
            "msisdnCount" : 1
        , 
        
            "_id" : 
                "txnTime_year" : 2015,
                "txnTime_month" : 4,
                "txnTime_day" : 27,
                "msisdn" : "9189877000"
            ,
            "msisdnCount" : 1
        , 
        
            "_id" : 
                "txnTime_year" : 2015,
                "txnTime_month" : 4,
                "txnTime_day" : 27,
                "msisdn" : "9189877667"
            ,
            "msisdnCount" : 1
        
    ],
    "ok" : 1

【讨论】:

这几乎是正确的....但是 msisdn = "91808070101" 是在同一日期 ....所以它在结果中的条目应该是这样的 - "_id" : "txnTime" : ISODate("2015-04-25"), "msisdn" : "91808070101" , "msisdnCount" : 3 , @AmitDas 我已经更新了这个效果的答案。如果您可以更详细地提出问题,具体目标,那就太好了,因为我一开始并不能真正理解您想要什么。我最终知道您想按日期对文档进行分组,格式为 YYYY-MM-DD,正如您最后在 cmets 中提到的那样。【参考方案2】:

使用 mongodb 4.0,您可以尝试 $toDate 聚合将毫秒转换为日期格式

db.collection.aggregate([
   "$match":  
    "campaignId" : 1 , 
    "txnTime" :  
      "$gte" : 1429554600000 , 
      "$lte" : 1430159400000
    
  ,
   "$project": 
    "toDate": 
      "$toDate": "$txnTime"
    
  
])

你可以试试here

【讨论】:

以上是关于在mongodb聚合管道中将毫秒转换为日期以进行分组?的主要内容,如果未能解决你的问题,请参考以下文章

在 iOS 中将毫秒转换为日期

如何在 iOS/XCode 中将毫秒时间戳转换为日期和时间?

在javascript中将iso日期转换为毫秒

在Android中将日期和时间转换为毫秒

使用 mongodb 聚合管道按升序向集合中的所有记录添加日期

将 Mongodb 聚合管道转换为 C# .Net Core