[MongoDB] E11000 duplicate key error index の code 11000 と 11001 の違い
MongoDB version 2.4.5 で unique index による duplicate key error index エラー発生時の error code には 11000 と 11001 があるのですが、その違いについて調べてみました。
事前準備
> db.version() 2.4.5 > db.so.drop(); > db.so.insert( { foo: 5 } ); > db.so.ensureIndex( { foo: 1 }, { unique: true } ); > db.so.insert( { foo: 6 } ); |
新規追加系メソッド insert のケース
db.collection.insert() で duplicate key error index エラーが発生したときは 11000 のエラーコードを返します。
> db.so.insert( { foo: 5 } ); E11000 duplicate key error index: test.so.$foo_1 dup key: { : 5.0 } > db.getPrevError(); { "err" : "E11000 duplicate key error index: test.so.$foo_1 dup key: { : 5.0 }", "code" : 11000, "n" : 0, "nPrev" : 1, "ok" : 1 } |
更新系メソッド update / save のケース
db.collection.update() や db.collection.save() などの更新系のメソッドで duplicate key error index エラーが発生したときは 11001 のエラーコードを返します。
このときに紛らわしいのは、エラーメッセージ E11000 duplicate key error index に含まれているエラーコードが 11000 ということです。
> db.so.update( { foo: 6 }, { $set: { foo: 5 } } ); E11000 duplicate key error index: test.so.$foo_1 dup key: { : 5.0 } > db.getPrevError(); { "err" : "E11000 duplicate key error index: test.so.$foo_1 dup key: { : 5.0 }", "code" : 11001, "n" : 0, "nPrev" : 1, "ok" : 1 } |
> var so6 = db.so.findOne( { foo: 6 } ) > so6.foo = 5 5 > db.so.save( so6 ) E11000 duplicate key error index: test.so.$foo_1 dup key: { : 5.0 } > db.getPrevError(); { "err" : "E11000 duplicate key error index: test.so.$foo_1 dup key: { : 5.0 }", "code" : 11001, "n" : 0, "nPrev" : 1, "ok" : 1 } |
まとめ
MongoDB version 2.4.5 では、エラーメッセージは E11000 duplicate key error index と同じだけど、エラーコードは 11000 と 11001 の2種類があるバグっぽい処理になっていました。
このため、プログラム上で duplicate key error を処理したいときは if(err.code === 11000 || err.code === 11001) みたいな感じで扱うといいかもしれません。
なお MongoDB version 3.0.2 で試してみたところエラーコードは 11000 に統一されているようでした。
なので、err.code === 11001 だけのコードは MongoBD を upgrade したタイミングで動かなくなってしまうので注意が必要そうです。
> db.version() 3.0.2 > db.so.insert( { foo: 5 } ); WriteResult({ "nInserted" : 0, "writeError" : { "code" : 11000, "errmsg" : "E11000 duplicate key error index: test.so.$foo_1 dup key: { : 5.0 }" } }) > db.so.update( { foo: 6 }, { $set: { foo: 5 } } ); WriteResult({ "nMatched" : 0, "nUpserted" : 0, "nModified" : 0, "writeError" : { "code" : 11000, "errmsg" : "E11000 duplicate key error index: test.so.$foo_1 dup key: { : 5.0 }" } }) > var so6 = db.so.findOne( { foo: 6 } ) > so6.foo = 5 5 > db.so.save( so6 ) WriteResult({ "nMatched" : 0, "nUpserted" : 0, "nModified" : 0, "writeError" : { "code" : 11000, "errmsg" : "E11000 duplicate key error index: test.so.$foo_1 dup key: { : 5.0 }" } }) |
以上です。