2016-08-09 2 views
3

와 $ INC 여러 문서 나는 다음과 같은 코드를 가지고 :MongoDB의 : 고유 인덱스

db.foo.insert([{_pos:1,b:12},{_pos:2,a:23},{_pos:3,c:12}]) 
db.foo.createIndex({ "_pos" : 1 }, { unique: true }) 
db.foo.update({}, { "$inc" : {"_pos" : 1} }, { multi : true }) 

마지막 줄은 나에게 다음과 같은 오류 제공합니다 도움이되지 않는 쿼리에 $isolated 추가

E11000 duplicate key error index: JsonTableTemp.foo.$_pos_1 dup key: { : 2.0 }

을 .

먼저 인덱스를 삭제하지 않고 _pos 필드를 증가시킬 수 있습니까?

나는 MongoDB를를 사용 3.2.6

+0

방금 ​​시도해 본 결과 createIndex가 오류를 던졌습니다. 두 번째 줄에서 {unique : true}를 제거했을 때 실제로 업데이트가 완벽하게 작동했습니다. – dyouberg

+0

@dyouberg : 왜 createIndex가 실패 했나요? 어떤 몽고 버전을 사용하고 있습니까? – Dreamcooled

+0

몽고 버전 3.2.0 > db.foo.createIndex ({ "_pos": 1}, {독특한 : TRUE}) { \t "확인": 0, \t "에 errmsg": "E11000 키 오류를 중복 컬렉션 : test.foo 인덱스 : _pos_1 dup 키 : {: 1.0} ", \t"코드 ": 11000 } – dyouberg

답변

2

좋아 내가

당신이 인덱스가 고유하고 있습니다 때문에 ... 그것을 가지고 - 값이 지금 같은 값을 공유 할 수 없습니다. 값은 [1,2,3]입니다. increment은 MongoDB의 원자 연산이므로 한 번에 하나씩 발생합니다 ... 먼저 [2,2,3], [2,3,3], 마지막으로 [2,3,4]입니다.

증명하려면 ... 간단히 값을 [3,2,1]과 반대 방향으로 시작하십시오.

> db.foo5.insert([{_pos:3,b:12},{_pos:2,a:23},{_pos:1,c:12}]) 
BulkWriteResult({ 
    "writeErrors" : [ ], 
    "writeConcernErrors" : [ ], 
    "nInserted" : 3, 
    "nUpserted" : 0, 
    "nMatched" : 0, 
    "nModified" : 0, 
    "nRemoved" : 0, 
    "upserted" : [ ] 
}) 
> db.foo5.createIndex({ "_pos" : 1 }, { unique: true }) 
{ 
    "createdCollectionAutomatically" : false, 
    "numIndexesBefore" : 1, 
    "numIndexesAfter" : 2, 
    "ok" : 1 
} 
> db.foo5.find() 
{ "_id" : ObjectId("57a9f76cb28f053d25a821a5"), "_pos" : 3, "b" : 12 } 
{ "_id" : ObjectId("57a9f76cb28f053d25a821a6"), "_pos" : 2, "a" : 23 } 
{ "_id" : ObjectId("57a9f76cb28f053d25a821a7"), "_pos" : 1, "c" : 12 } 
> db.foo5.update({}, { "$inc" : {"_pos" : 1} }, { multi : true }) 
WriteResult({ "nMatched" : 3, "nUpserted" : 0, "nModified" : 3 }) 
> db.foo5.find() 
{ "_id" : ObjectId("57a9f76cb28f053d25a821a5"), "_pos" : 4, "b" : 12 } 
{ "_id" : ObjectId("57a9f76cb28f053d25a821a6"), "_pos" : 3, "a" : 23 } 
{ "_id" : ObjectId("57a9f76cb28f053d25a821a7"), "_pos" : 2, "c" : 12 } 
+0

그래, 나도 그걸 알았지 만, 명령을 변경하는 것은 정말로 나를위한 선택 사항이 아닙니다. 그것이 내가 질문 한 이유입니다. ** 인덱스를 먼저 삭제하지 않고 _pos 필드를 어떻게 늘릴 수 있습니까? – Dreamcooled

+0

그래, 인덱스의 고유 한 부분을 제거해야하거나 일부 동시성 제어 양식을 작업에 적용해야하는 것처럼 보입니다. 나는 또한 격리 된 $를 시도하고 일하기 위하여 그것을 얻을 수 없었다. 색인이 고유해야 할 필요가있는 이유가 있습니까? – dyouberg

+0

고유 한 부분을 제거하면 고유 한 클라이언트 쪽을 보장해야합니다. 또한 고유 인덱스가 정상 인덱스와 비교하여 일부 작업 속도를 높일 것이라고 생각합니다. – Dreamcooled