web-dev-qa-db-ja.com

例外:BSONタイプEOOから日付に変換できません

次の集計クエリを実行すると問題が発生します。

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

この問題を回避するにはどうすればよいですか。関連する質問を見つけました

関連するスタックオーバーフローの質問

しかし、物事を成し遂げる方法はわかりません。

28
jsbisht

おそらく、BSON Dateではないcreated_at値を持つ1つ以上のドキュメントがあり、それらの値をDateに変換するか削除して修正する必要があります。

これらのドキュメントは、次のような $not 演算子を使用する$typeクエリで見つけることができます。

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

created_at値が日付文字列の場合、更新が必要なドキュメントを見つけて、次のようなコードを使用してシェルで更新できます。

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

状況によっては、一部のドキュメントには日付フィールドが空であると想定されています。そのような場合、これを試すことができます(例を使用して):

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

この例では、フィールド「$ created_at」が見つからない場合は常に-1を取得します。他のすべての場合、Date月を取得します。

4
FRocha

関連する問題がありましたが、私の場合、日付フィールドは配列のメンバーであったため、エラーは「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 type Object」検索でゼロの検索結果も取得する人に役立つことを願っています

2
Skipwave

これを試してみてください、上記の問題の助けになります。

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

上記のコードは月ごとに取得します

データはISO形式でデータベースに入力され、簡単に操作できます。

1
Anurag Pandey

同様の問題があり、日付が存在するかどうかを確認して解決しました。

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日に誕生日を持つすべてのユーザーを取得しています。

1
facumedica

私は同じ問題を抱えていたので、一部のドキュメントの日付フィールドが欠落しているため、変換が失敗しました。これらを除外するために、match句を追加しました。しかし、もちろん、アプリ側でそれらが入力されない理由を調査しています。

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

このエラーは、データベース内のプロパティと比較して、集計内のプロパティに誤った名前を付けた場合にも表示される可能性があります。

たとえば、私のコードは

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

しかし、データベースのタイムスタンプをキャメルケース化していないので、単にprojects.timestampそれを修正しました。

0
Enda Molloy

最初に、データ型が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);})

今、あなたは2つの方法でそれを見つけることができます

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}}])
0
ABDUL JAMAL