[MongoDB] exception: can’t convert from BSON type EOO to Date の解決方法
MongoDB の aggregate で値が入ってない Date field に $year, $month を適用したところ exception: can’t convert from BSON type EOO to Date というエラーが発生して、解決した内容をご紹介します。
MongoDB データの前提
MongoDB に以下のようなデータが保存されている users collection があるとします。
// createdAt field が有る document db.users.save( { name: 'hoge', createdAt: ISODate('2017-01-01') }) db.users.save( { name: 'fuga', createdAt: ISODate('2017-02-02') }) db.users.save( { name: 'mogu', createdAt: ISODate('2017-02-20') }) // createdAt field が無い document db.users.save( { name: 'spam }) |
can’t convert from BSON type EOO to Date の解決方法
エラーが発生するクエリ
createdAt field に値が保存されていないにも関わらず $year, $month オペレーターを適用するとエラーが発生します。
db.users.aggregate({ $project: { createdAt: 1 } }, { $group: { _id: { year: { $year: "$createdAt" }, month: { $month: "$createdAt" } }, count: { $sum: 1 } } }); // 以下、実行結果 assert: command failed: { "ok" : 0, "errmsg" : "can't convert from BSON type EOO to Date", "code" : 16006 } : aggregate failed _getErrorWithCode@src/mongo/shell/utils.js:25:13 doassert@src/mongo/shell/assert.js:16:14 assert.commandWorked@src/mongo/shell/assert.js:290:5 DBCollection.prototype.aggregate@src/mongo/shell/collection.js:1312:5 @(shell):1:1 2018-02-02T23:04:34.794+0900 E QUERY [thread1] Error: command failed: { "ok" : 0, "errmsg" : "can't convert from BSON type EOO to Date", "code" : 16006 } : aggregate failed : _getErrorWithCode@src/mongo/shell/utils.js:25:13 doassert@src/mongo/shell/assert.js:16:14 assert.commandWorked@src/mongo/shell/assert.js:290:5 DBCollection.prototype.aggregate@src/mongo/shell/collection.js:1312:5 @(shell):1:1 |
エラーが発生しないクエリ
createdAt が Date Type なことをチェックするために $type: 9 を利用します。少し雑に比較するなら $ne: null や $exists: true なども使えます。
$year, $month など Date な値が渡ってくることを期待したオペレーターを使う場合は、$match で条件指定しておきましょうという話ですね。
db.users.aggregate({ $match: { createdAt: { $type: 9 // 雑に $ne: null や $exists: true も使える } } }, { $project: { createdAt: 1 } }, { $group: { _id: { year: { $year: "$createdAt" }, month: { $month: "$createdAt" } }, count: { $sum: 1 } } }); // 以下、実行結果 { "_id" : { "year" : 2017, "month" : 2 }, "count" : 2 } { "_id" : { "year" : 2017, "month" : 1 }, "count" : 1 } |
以上、MongoDB の aggregate メソッドでエラーに遭遇した現場からお送りしました。
参考情報
- mongodb – exception: can't convert from BSON type EOO to Date – Stack Overflow
- $year (aggregation) — MongoDB Manual
- $month (aggregation) — MongoDB Manual
- $type — MongoDB Manual