2016-07-13 4 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 문서 (AN 시작하는 경우 빈 콜렉션),
처음 삽입하면 "무시"하는 것입니다.

> 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에 이런 종류의 오류를받지입니까?


편집 : 나는 MongoDB를의 v.3.2.3

답변

1

그것을 그냥 _idname 필드를 업데이트하려고으로 첫 번째 경우에서 중복 인덱스 오류를 표시 할 이유가 없다 사용하고 동일한 가치를 지닌 동일한 기록의

쿼리가 일부 기존 _id 값과 다른 _id와 레코드를 업데이트하려고 당신이, 당신이 오류가 발생합니다

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

시도됩니다.

두 번째 경우에는 name 필드로 먼저 레코드를 만든 다음 다른 레코드에서 동일한 이름을 업데이트하려고 시도하면 name은 고유 인덱스이므로 오류가 발생합니다.

편집 : - 당신은 이미 즉 _id하는 레코드를 삽입하려고이 경우 당신이,

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

당신에게 오류를 줄 것이다

시도하는 경우는 고유하고 있습니다 동일한 _id 값으로 레코드를 하나 더 만들려고합니다.

upsert:true : - upsert가 true이고 쿼리 기준과 일치하는 문서가없는 경우 update()는 단일 문서를 삽입합니다.

upsert가 true이고 쿼리 조건과 일치하는 문서가있는 경우 update()는 업데이트를 수행합니다.

+0

몇 가지 시도를했는데 ** inserts ** 대신 ** upsert **를 사용하여 예외/오류가 발생했습니다. : "E11000 중복 키 오류 콜렉션 : test.foo index : _id_ dup 키 : {: \ "doe123 \"} "'. 그렇다면 왜 insert는 에러를 던지나요?하지만 upsert는 그렇지 않습니다. 그냥 조회하기 때문에 * "내가 뭔가를 업데이트해야합니까? 아니요? 내가 아무것도하지 않는 것보다"*? – Krenor

+1

'upsert : true '는 필드가 없다면 삽입 할 것임을 의미하고, 그렇지 않으면 그냥 값을 업데이트 할 것입니다. 'insert'의 경우 실제로'_id'에 대한 값이 중복되는 레코드를 삽입하려고합니다. 나는 그것이 지금 분명하기를 바란다. – Shrabanee

+0

나는 내 대답도 업데이트했다. – Shrabanee