2016-07-13 6 views
2

私はNoSQLデータベースを全く新しくしており、現在MongoDBで働いています。MongoDB - _idインデックスが重複エントリでエラーを投げないのはなぜですか?

upserting a duplicate _id文書の場合、デフォルトの_idインデックスでエラーが発生しない理由を理解しようとしています。ドキュメントに記載されているように

_idデフォルト

によって一意のインデックスである(それはここで独特のフラグは表示されませんが...)だから、

> db.foo.getIndexes(); 
[ 
    { 
     "v" : 1, 
     "key" : { 
      "_id" : 1 
     }, 
     "name" : "_id_", 
     "ns" : "test.foo" 
    } 
] 
> 

upserting文書(使用を開始するとき空のコレクション)、
最初に挿入して「無視」しているように見える場合。

> db.foo.update({ _id: 'doe123'}, { _id: 'doe123', name: 'John Doe'}, { upsert: true}); 
WriteResult({ "nMatched" : 0, "nUpserted" : 1, "nModified" : 0, "_id" : "doe123" }) 

> db.foo.update({ _id: 'doe123'}, { _id: 'doe123', name: 'John Doe'}, { upsert: true}); 
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 0 }) 

だから私は別のものを試してみましたが、「名前」にunique indexを作成しました。

重複する名前をupsertingの結果:

> db.foo.update({ _id: 'foo456'}, { _id: 'foo456', name: 'John Doe'}, { upsert: true}); 
WriteResult({ 
    "nMatched" : 0, 
    "nUpserted" : 0, 
    "nModified" : 0, 
    "writeError" : { 
     "code" : 11000, 
     "errmsg" : "E11000 duplicate key error collection: test.foo index: name_1 dup key: { : \"John Doe\" }" 
    } 
}) 

なぜ私は重複_idにこの種のエラーを得ていないのですか?


EDIT:私はのMongoDB v.3.2.3

答えて

1

をそれだけで_idnameフィールドを更新しようとしているとして、最初のケースで重複したインデックスのエラーを表示する理由はない使用しています同じ値の同じレコードの

クエリは、いくつかの既存の_id値と異なる_idでレコードを更新しようとしているとして、あなたは、あなたがエラーを取得します

db.foo.update({ _id: '1098'}, { _id: 'doe123', name: 'John Doe'}, { upsert: true}); 

をしようとした場合。

nameフィールドで最初にレコードを作成し、別のレコードで同じ名前を更新しようとしています。これは、nameが一意のインデックスであるためエラーが発生します。

編集: -

あなたは

db.foo.insert({ _id: 'doe123', name: 'John Doe'}); 

をしようとしている場合は、既に存在すなわち_idあるレコードを挿入しようとしている。この場合のように、あなたにエラーを与えるには、ユニークであり、あなたは、同一の_id値を持つレコードをもう1つ作成しようとしています。

upsert:true: - upsertがtrueで、クエリ条件に一致するドキュメントがない場合、update()は単一のドキュメントを挿入します。

upsertがtrueで、クエリ条件に一致するドキュメントがある場合、update()は更新を実行します。

+0

いくつかのことを試してみましたが、** upsert **の代わりに** insert **を使用すると予想される例外/エラーが発生しました:E11000重複キーエラーコレクション:test.foo index:_id_ dupキー:{:\ "doe123 \"} "'では、なぜinsertは私にエラーを投げますが、upsertはしませんか?見上げただけなので*「何かを更新する必要はありますか?いいえ?私は何もしません」* – Krenor

+1

'upsert:true 'は、フィールドがなければ挿入することを意味し、そうでなければ値を更新するだけです。 'insert'の場合、実際に' _id'に値が重複しているレコードを挿入しようとします。今はっきりしていることを願っています。 – Shrabanee

+0

私は私の答えも更新しました。 – Shrabanee

関連する問題