异常:无法从 BSON 类型 EOO 转换为 Date

Exception: can't convert from BSON type EOO to Date

我遇到了 运行 以下聚合查询的问题:

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.

但它没有告诉我如何完成事情。

您可能有一个或多个文档的 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);
})

在某些情况下,某些文档应该有空的日期字段。在这些情况下,您可以尝试这样做(使用您的示例):

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

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

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

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

上面的代码获取月份

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

我有一个相关问题,但在我的例子中,日期字段是数组的成员,所以错误是 "can't convert BSON type Object to Date"。

我需要从 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 type Object" 搜索

中也得到零搜索结果的人有所帮助

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

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 日的用户。

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

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

如果您在聚合中根据属性在数据库中的名称错误地命名了属性,也会出现此错误。

例如我的代码是

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

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

首先需要检查数据类型是否为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}}])

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


    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);
    });

在我的例子中,我不得不使用“$toDate”并且它起作用了:

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