首页 文章

MongoDB中的数据类型转换

提问于
浏览
23

我有一个名为Document in MongoDB的集合 . 此集合中的文档具有以ISO日期类型存储的名为CreationDate的字段 . 我的任务是计算每天创建的文档数量,并按异步数量排序 . 输出格式必须是[{_id:'yyyy-MM-dd',cnt:x}] . 我尝试使用如下聚合框架 .

db.Document.aggregate( 
    , {$project: {_id:1, Year:{$year:'$CreationDate'}, Month:{$month:'$CreationDate'}, Date:{$dayOfMonth:'$CreationDate'}}}
    , {$group: {_id:{$concat:['$Year', '-', '$Month', '-', '$Date']}, cnt:{$sum:1}}}
    , {$sort:{'cnt':-1}}
);

代码给出了如下错误:

$concat only supports strings, not NumberInt32

我明白这是因为$ year,$ month和$ dayOfMonth都返回了数字 . 可以将_id字段组合为对象,并在应用程序级别以所需格式重新格式化它 .

但从技术角度来看,我有两个问题:

  • 如何在MongoDB shell中将数字转换为字符串?在这种情况下,$ year的输出可以转换为字符串并在$ concat中使用 .

  • 有没有更好的方法将ISODate输出格式化为各种日期格式?在许多情况下,我们只需要ISODate的某些部分,例如:日期组件或时间部分 . 是否有任何MongoDb内置运营商来实现这一目标?

提前感谢任何建议 .

5 回答

  • 4

    您可以使用$concat执行此操作,但首先需要通过$substr转换为字符串,同时处理双位数字的情况:

    db.Document.aggregate([ 
        { "$group": { 
            "_id":{ 
                "$concat": [
                     { "$substr": [ { "$year": "$CreationDate" }, 0, 4 ] },
                     "-",
                     { "$cond": [
                         { "$gt": [ { "$month": "$CreationDate" }, 9 ] },
                         { "$substr": [ { "$month": "$CreationDate" }, 0, 2 ] },
                         { "$concat": [
                             "0",
                             { "$substr": [ { "$month": "$CreationDate" }, 0, 1 ] },
                         ]},
                     ]},
                     "-",
                     { "$cond": [
                         { "$gt": [ { "$dayOfMonth": "$CreationDate" }, 9 ] },
                         { "$substr": [ { "$dayOfMonth": "$CreationDate" }, 0, 2 ] },
                         { "$concat": [
                             "0",
                             { "$substr": [ { "$dayOfMonth": "$CreationDate" }, 0, 1 ] },
                         ]}
                     ]}
                 ]
             },
             { "cnt": { "$sum": 1 } }
        }}
        { "$sort":{ "cnt" :-1 }}
    ]);
    

    可能更好的是仅使用日期数学,这会返回一个纪元时间戳值,但在后期处理中很容易使用日期对象:

    db.Document.aggregate([
        { "$group": {
            "_id": {
                "$subtract": [
                    { "$subtract": [ "$CreationDate", new Date("1970-01-01") ] },
                    { "$mod": [
                        { "$subtract": [ "$CreationDate", new Date("1970-01-01") ] },
                        1000 * 60 * 60 * 24
                    ]}
                ]
            },
            "cnt": { "$sum": 1 }
        }},
        { "$sort": { "cnt": -1 } }
    ])
    
  • 27

    将ISODate转换为各种日期格式的另一种更简单方法是使用$dateToString aggregation operator .

    db.collection.aggregate([
        { $group: {
            _id: { $dateToString: { format: "%Y-%m-%d %H:%M", date: "$CreationDate" } },
            count: { $sum: 1 }
        }},
        { $sort : { count: -1 }}
    ])
    
  • 3

    尼尔回答了它的权利,但有一点点错误 . 在条件中(检查月份和日期的数量是否需要以0为前缀)不是 $gt 而是 $lte .

    使用 $lte 时,只有一个数字的月份和天数将以0开头 .

    例如:2014-10- 0 3,2014- 0 8- 0 3 .

  • 13

    FOR MONGO> = 3.0(2015年之后)

    如果一些可怜的灵魂在2017年偶然遇到这个问题,就像我一样:从Mongo 3.0开始,现在有一个dateToString运营商可用

    这意味着如果你有正确的Date(),你应该可以做到:

    db.Document.aggregate( 
        , {$project: {_id:1, CreationDate:1}
        , {$group: {
             _id : { $dateToString: { format: "%Y-%m-$d", date: "$CreationDate" } },
             cnt:{$sum:1}}}
        , {$sort:{'cnt':-1}}
    );
    

    对于我们这些碰巧将日期存储在非日期字段中的人(快乐!),您可以在项目步骤中创建一个新的Date()对象 . 在我的例子中,日期存储为毫秒(整数),我将毫秒数添加到0日期 .

    db.Document.aggregate( 
        , {$project: {
             _id:1, 
             CreationDate: {"$add": [ new Date(0), "$CreatedOn" ]}
    }
        , {$group: {
             _id : { $dateToString: { format: "%Y-%m-$d", date: "$CreationDate" } },
             cnt:{$sum:1}}}
        , {$sort:{'cnt':-1}}
    );
    
  • 2

    要将日期格式转换为“xxxx-xx-xx”

    db.getCollection('analytics').aggregate([
     {$project: {
         day: {$dayOfMonth: "$createdAt"},
         month: {$month: "$createdAt"},
         year: {$year: "$createdAt"},
         }
      },
      {$project: {
          day: {$concat:["0", {$substr:["$day",0, 2]}]},
         month: {$concat:["0", {$substr:["$month",0, 2]}]},
         year: {$substr:["$year",0, 4]},
          }
      },
      {$project: {date: {$concat: [{$substr:["$year",0, 4]},"-", {$substr:["$month",0, 2]},"-", {$substr:["$day",0, 2]}]}}},
    ]);
    

相关问题