【问题标题】:Exception: can't convert from BSON type EOO to Date例外:无法从 BSON 类型 EOO 转换为日期
【发布时间】:2015-04-09 13:26:22
【问题描述】:

运行以下聚合查询时遇到问题:

db.snippets.aggregate([ { '$project': { month: { '$month': '$created_at' }} } ])

同样的错误信息是:

assert: command failed: {
        "errmsg" : "exception: can't convert from BSON type EOO to Date",
        "code" : 16006,
        "ok" : 0 } : aggregate failed

如何解决这个问题?我发现了一个相关的问题:MongoDB: can't convert from BSON type EOO to Date

但它并没有告诉我如何完成工作。

【问题讨论】:

标签: mongodb date mongoose aggregation-framework


【解决方案1】:

在我的情况下,我不得不使用“$toDate”并且它起作用了:

db.snippets.aggregate([ { '$project': { month: { '$month': {$toDate: '$created_at'} }} } ])

【讨论】:

    【解决方案2】:

    首先,您可以识别导致问题的特定字段,如下所示:

    
        db.collectionName.find( { 'dateField' : { $type : 2 } } )
    
    

    上述行检查并找到所有字段名称为“dateField”且类型为String(称为$type - 2)的文档。

    一旦被识别和验证,我们可以修改这些记录如下:

    
        db.collectionName.find( { 'dateField' : { $type : 2 } } ).forEach( function (x) {   
          x.dateField = new ISODate(x.dateField);
          db.collectionName.save(x);
        });
    
    

    【讨论】:

      【解决方案3】:

      首先,您需要检查数据类型是否在 ISODate 中。如果不是,您可以按照以下示例更改数据类型。

      db.collectionName.find().forEach(function(each_object_from_collection){each_object_from_collection.your_date_field=new ISODate(each_object_from_collection.your_date_field);db.collectionName.save(each_object_from_collection);})
      

      现在你可以通过两种方式找到它

      db.collectionName.find({ $expr: {$eq: [{ $year: "$your_date_field" }, 2017]}});
      

      或者通过聚合

      db.collectionName.aggregate([{$project: {field1_you_need_in_result: 1,field12_you_need_in_result: 1,your_year_variable: {$year: '$your_date_field'}, your_month_variable: {$month: '$your_date_field'}}},{$match: {your_year_variable:2017, your_month_variable: 3}}])
      

      【讨论】:

        【解决方案4】:

        我遇到了类似的问题,并解决了它检查日期是否存在。

        db.users.aggregate([
        {$project:{day:  { $cond: ["$bd", { $dayOfMonth: "$bd" }, -1] },
                   month:  { $cond: ["$bd", { $month: "$bd" }, -1] },
                   year:  { $cond: ["$bd", { $year: "$bd" }, -1] }
                   }},
        {$match:{"month":1, "day":15}}
        ])
        

        我的日期字段是 bd,通过该匹配,我将获得所有生日在 1 月 15 日的用户。

        【讨论】:

          【解决方案5】:

          如果您错误地将聚合中的属性命名为相对于它们在数据库中的名称,也会出现此错误。

          例如我的代码是

          $group: {
                  _id: {$week: "$projects.timeStamp"},
                  total: { $sum: "$projects.hours"  }
              }
          

          但我的数据库中没有驼峰时间戳,所以只需修改为projects.timestamp 即可修复它。

          【讨论】:

            【解决方案6】:

            我遇到了同样的问题,我认为某些文档缺少日期字段导致转换失败。我刚刚添加了一个匹配子句来过滤掉这些。但是,我当然正在我的应用程序方面调查为什么它们没有被填充。

            db.snippets.aggregate([
              {
                '$match': {
                  'created_at': {
                    "$exists": true
                  }
                }
              },
              {
                '$project': {
                  month: {
                    '$month': '$created_at'
                  }
                }
              }
            ])
            

            【讨论】:

              【解决方案7】:

              我遇到了一个相关问题,但在我的情况下,日期字段是数组的成员,因此错误是“无法将 BSON 类型对象转换为日期”。

              我需要从 possibleTripDateTimes 数组中的日期获取星期几。

              示例文档:

              {
              "possibleTripDateTimes" : [
                  {
                      "tripDateTime" : ISODate("2015-08-01T06:00:00.000-0700")
                  }
              ]
              }
              

              解决方法是简单地使用点符号来处理数组成员字段。

              db.trips.aggregate([
                {
                     $project: {
                       departTime: {
                         $map: {
                           input: "$possibleTripDateTimes.tripDateTime",
                           as: "dateTime",
                           in: { $dayOfWeek: "$$dateTime" }
                         }
                 }
                }
              }
              ]
              );
              

              我希望这对在“BSON 类型对象”搜索中也获得零搜索结果的人有所帮助

              【讨论】:

              • 啊!!这太酷了。你为我节省了很多愚蠢的搜索时间!谢谢人:)
              【解决方案8】:

              试试这个,它对我上面的问题有帮助。

              db.snippets.aggregate([{
              '$project': {
                  month: { $substr: ["$created_at", 5, 2] }
              }
               }]);
              

              以上代码按月计算

              数据以 ISO 格式输入数据库,然后可以轻松使用。

              【讨论】:

                【解决方案9】:

                在某些情况下,某些文档应该有空的日期字段。在这些情况下,你可以试试这个(使用你的例子):

                db.snippets.aggregate([ { '$project': { month:  
                 { $cond: [{ $ifNull: ['$created_at', 0] }, { $month: '$created_at' }, -1] }} } ])
                

                在这个例子中,只要没有找到“$created_at”字段,我们就会得到 -1。对于所有其他情况,我们将获得日期月份。

                【讨论】:

                  【解决方案10】:

                  您可能有一个或多个文档的 created_at 值不是 BSON Date,您需要通过将这些值转换为 Date 或删除它们来解决此问题。

                  您可以通过使用$type 运算符的$not 查询找到这些文档,例如:

                  db.snippets.find({created_at: {$not: {$type: 9}}})
                  

                  如果 created_at 值是日期字符串,您可以找到需要更新的文档,然后使用以下代码在 shell 中更新它们:

                  db.snippets.find({created_at: {$not: {$type: 9}}}).forEach(function(doc) {
                      // Convert created_at to a Date 
                      doc.created_at = new Date(doc.created_at);
                      db.snippets.save(doc);
                  })
                  

                  【讨论】:

                  • 你成就了我的一天。我因此被困了很长一段时间。
                  • @JohnnyHK 这个查询不会只找到没有 BSON 日期的文档吗?如何查找和更新所有非 BSON 日期?
                  • @user137717 将.find(conditions) 推断为.update(conditions, update)
                  • @JohnnyHK 谢谢。你让我开心。
                  猜你喜欢
                  • 2013-04-18
                  • 2017-04-22
                  • 2014-07-16
                  • 2017-11-04
                  • 2013-01-25
                  • 2017-06-17
                  • 2021-03-22
                  • 2017-09-23
                  相关资源
                  最近更新 更多