【问题标题】:Mongodb exception can't convert from BSON type EOO to DateMongodb 异常无法从 BSON 类型 EOO 转换为 Date
【发布时间】:2017-04-22 13:12:19
【问题描述】:

我正在尝试根据年、月、日对我的 mongodb 查询进行分组。

我的数据存储数据库如下

{
"installAt" : "2016-08-01T10:24:38.502Z",
"success" : true
"app" : "web"
}

我试图在上面实现的查询

db.sampleCollection.aggregate(
       [
          {
            $group : {
               _id : { month: { $month: "$installAt" }, day: { $dayOfMonth: "$installAt" }, year: { $year: "$installAt" } },
               count: { $sum: 1 }
            }
          }
       ]
    )

但我收到此错误

 assert: command failed: {
        "errmsg" : "exception: can't convert from BSON type EOO to Date",
        "code" : 16006,
        "ok" : 0
} : aggregate failed
Error: command failed: {
        "errmsg" : "exception: can't convert from BSON type EOO to Date",
        "code" : 16006,
        "ok" : 0
} : aggregate failed
    at Error (<anonymous>)
    at doassert (src/mongo/shell/assert.js:11:14)
    at Function.assert.commandWorked (src/mongo/shell/assert.js:244:5)
    at DBCollection.aggregate (src/mongo/shell/collection.js:1149:12)
    at (shell):1:23
2016-12-07T19:48:25.541+0530 Error: command failed: {
        "errmsg" : "exception: can't convert from BSON type EOO to Date",
        "code" : 16006,
        "ok" : 0
} : aggregate failed at src/mongo/shell/assert.js:13

这个例外的一个原因可能是(我不确定)因为

"installAt" : "2016-08-01T10:24:38.502Z"

不是mongodb日期格式而是String

如果这是问题所在,那么解决此问题的一种方法是将这些字段更新为 ISODate 格式,例如

ISODate("2016-08-01T10:24:38.502Z")

但由于某些原因,我目前无法修改我的数据库。

我可以使用上述代码或替代代码实现分组吗? (不更新数据库)

【问题讨论】:

    标签: mongodb mongodb-query


    【解决方案1】:

    是的,这就是问题所在。你的日期是字符串。

    我插入了一个类似的文档

    db.date1.insert(
    { "installAt" : new ISODate("2016-08-01T10:24:38.502Z"), 
    "success" : true ,"app" : "web" })
    

    并运行您的查询

    db.date1.aggregate(
           [
              {
                $group : {
                   _id : { month: { $month: "$installAt" }, day: { $dayOfMonth: "$installAt" }, year: { $year: "$installAt" } },
                   count: { $sum: 1 }
                }
              }
           ]
        )
    

    还给我

    { "_id" : { "month" : 8, "day" : 1, "year" : 2016 }, "count" : 1 }
    

    现在,如果您不热衷于重新创建您的收藏并转换 installAt as date 你可以做的是你可以改变字段类型 使用 $type 运算符。

    如何做到这一点的示例是

    var cursor = db.date1.find(); 
    while (cursor.hasNext()) { 
      var doc = cursor.next(); 
      db.date1.update({_id : doc._id}, {$set : {installAt: new ISODate(doc.installAt) }});
    }
    

    【讨论】:

    • 感谢您的帮助。您的解决方案将起作用,但目前由于某种原因我无法更新数据库
    • 您的解决方案有效,但您没有使用 $type 运算符。
    【解决方案2】:

    您可以使用 $substr 对月份的年份和日期进行分组,从而轻松实现这一目标。

    db.sampleCollection.aggregate({
        $group: {
            _id: {
                "year": {
                    "$substr": ["$installAt", 0, 4]
                },
                "day": {
                    "$substr": ["$installAt", 5, 2]
                }
            },
            count: {
                $sum: 1
            }
        }
    })
    

    【讨论】:

      【解决方案3】:

      您可以通过以下方式做到这一点,但这不是唯一的方式

      varcursor=db.sampleCollection.find({"installAt": { "$exists": true }});
      while(cursor.hasNext()){
        vardoc=cursor.next();
        db.tempcollection.insert({ "_id": doc._id, "installAt": newISODate(doc.installAt), "success": doc.success, "app": doc.web })
      };
      
      db.tempCollection.aggregate([
        {
          $group: {
            _id: {
              month: {
                $month: "$installAt"
              },
              day: {
                $dayOfMonth: "$installAt"
              },
              year: {
                $year: "$installAt"
              }
            },
            count: {
              $sum: 1
            }
          }
        }
      ])
      

      在这种方法中,我们正在创建一个新集合“tempcollection”,因为要求是不修改/更新现有集合。完成操作后,我们可以删除此临时集合。

      【讨论】:

        猜你喜欢
        • 2013-04-18
        • 2014-07-16
        • 2015-04-09
        • 2020-11-09
        • 2020-10-23
        • 2017-09-23
        • 2018-05-24
        • 2017-11-04
        相关资源
        最近更新 更多