2014-08-28 3 views
1

10-1500 만 개의 항목이있는 mongodb 데이터베이스가 있습니다. 각각에 대해 처음에는 존재하지 않는 필드를 업데이트해야합니다. 예기치 않은 서버 종료로 인해 응용 프로그램이 다운되었다고 가정하면 나머지 항목을 업데이트하는 것이 가장 좋습니다.

field: {$exists: false}을 사용해야하나요, 아니면 전체 컬렉션을 살펴보고 해당 필드가있는 경우 각 문서를 확인해야합니까, 그렇다면 업데이트를 수행해야합니까? 필자가 생각하기에 인덱스를 필드의 존재와 연관시킬 수 없으므로 $ exists는 기본적으로 같은 것이다. 어느 것이 더 빠를 것이며 그 이유는 무엇입니까?

이 필드의 값은 문서의 다른 필드에 따라 달라 지므로 다중을 수행 할 수 없습니다 : true 업데이트.

솔루션 : @DhruvPathak 및 @Sammaye는 (그래서 당신은 인덱스 필드의 존재에 링크 할 수 없습니다), 인덱스 데이터에 관련되는 동안이 아니라 필드 자체 제안으로 $가 활용할 수 있습니다 존재 필드가있는 문서의 색인 수는 크게 증가합니다.

추가 : 약간의 측면 탐색이지만, 이제 응용 프로그램이 충돌 한 이유를 알았습니다. 서버는 커서가 너무 오래 사용 되었기 때문에 커서를 시간 초과했습니다 (컬렉션의 크기를 고려할 때). 설명 된대로 batch_size을 사용하여 피할 수 있습니다 here.

+0

[explain()] (http://docs.mongodb.org/manual/reference/method/cursor.explain/) 도움이 될 수도 있습니다. – soulcheck

+1

문서에 field_exists 필드를 추가 할 수 있습니다. 기본값은 false입니다. 문서를 업데이트하는 경우 "field_exists"를 true로 설정합니다. 또한이 필드에 대한 색인을 쉽게 작성할 수 있습니다. – thomas

+0

@soulcheck 사실, explain은 $ exists 쿼리에 도움이 될 것입니다. 그러나 수동으로 각 필드를 업데이트하는 다른 경우에는 설명이 각 루프의 효율성에 대한 데이터를 제공 할 수 없습니다. 이것은 pymongo 스크립트입니다. – thehousedude

답변

1

네, 맞습니다. 두 경우 모두 mongodb가 전체 세트를 반복 할 것입니다. 이 작업을 수행하는 다른 좋은 방법은 $exists 연산자를 사용하여 대상 필드를 선택한 다음 인덱스를 삭제하는 것입니다. 생성 된 색인이 $ 존재하는 경우 유용하지 않으므로 생성 된 색인이 희소하지 않은지 확인하십시오. http://docs.mongodb.org/manual/core/index-sparse/

+0

감사합니다. 문제의 필드는 정수입니다. 그래서 오름차순 인덱스가 문제가되지 않을까요? – thehousedude

+1

인덱스를 만든 다음 제거하면 오버 헤드가 추가됩니다. – vmr

1

검색어에 explain()이 추가되면 $existsBasic 커서가 있음을 알 수 있습니다. 즉, 컬렉션의 모든 문서를 검색합니다. 따라서 전체 컬렉션을 살펴보고 각 문서가 해당 필드가 있는지 확인하고 업데이트가 필요한 경우 각 문서를 확인하십시오. $exists의 성능은 컬렉션 전체를 검색하는 것과 비슷합니다.

2

이에 대한 필자는 필드

의 존재와 인덱스를 연결할 수 없기 때문에 지금 MongoDB를 2.6를 위해 할 수있는 Acccording 있다는 것입니다 :에서

> use f 
switched to db f 
> db.t.insert({a:1}) 
WriteResult({ "nInserted" : 1 }) 
> db.t.ensureIndex({b:1}) 
{ 
     "createdCollectionAutomatically" : false, 
     "numIndexesBefore" : 1, 
     "numIndexesAfter" : 2, 
     "ok" : 1 
} 
> db.t.find({b:{$exists:false}}) 
{ "_id" : ObjectId("53e88a7dde0848171584d296"), "a" : 1 } 
> db.t.find({b:{$exists:false}}).explain() 
{ 
     "cursor" : "BtreeCursor b_1", 
     "isMultiKey" : false, 
     "n" : 1, 
     "nscannedObjects" : 1, 
     "nscanned" : 1, 
     "nscannedObjectsAllPlans" : 1, 
     "nscannedAllPlans" : 1, 
     "scanAndOrder" : false, 
     "indexOnly" : false, 
     "nYields" : 0, 
     "nChunkSkips" : 0, 
     "millis" : 0, 
     "indexBounds" : { 
       "b" : [ 
         [ 
           null, 
           null 
         ] 
       ] 
     }, 
     "server" : "ubuntu:27017", 
     "filterSet" : false 
} 
> 

내가 찾을 수있는 것은 v2.0에서 추가 된 것으로 보인다 : https://stackoverflow.com/a/7503114/383478 불행히도 그 대답의 문서 링크는 죽었다.

v2.0 이전 버전을 사용할 수 없다면 질의하는 것이 더 빠를 것입니다.

+0

고마워, 나는 몰랐다. 그것은 오름차순 색인 인 것 같습니다. 내가 찾은 다른 질문에서 사람들은 인덱스를 실제 가치가 아닌 실제 필드의 존재와 연관시키기를 원했습니다. 이것도 사용할 수 있지만 좋습니다. – thehousedude

+1

@thehousedude 이것은 mongodb이 키 저장소의 경우 더 좋을 것입니다. mongodb은 최근에 JIRA에서 내가 쓴 것을 http://rocksdb.org/에서 평가했습니다. 그게 그들이 플러그 형 스토리지 엔진을 만드는 이유 중 하나입니다. 그래서 당신은 MySQL과 같은 다른 기술자와 같은 것을 얻을 수 있습니다. – Sammaye

관련 문제