[MongoDB] E11000 duplicate key error index の code 11000 と 11001 の違い

Tadashi Shigeoka ·  Mon, September 14, 2015

MongoDB version 2.4.5 で unique index による duplicate key error index エラー発生時の error code には 11000 と 11001 があるのですが、その違いについて調べてみました。

MongoDB | モンゴディービー

事前準備

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

以上です。

参考情報