2012-12-19 2 views
1

MongoDB :: Databaseing에 Mongoid :: Versioning이 가능한 콜렉션이 있습니다. 불행히도 일부 문서는 크기가 매우 큽니다. 나는 711K가 넘는 것을 본다. 이것은 값 비싼 디스크 I/O와 값 비싼 읽기/쓰기 시간을 만듭니다. 나는이 컬렉션 (거의 2 백만 건의 문서가 있음)을 통과하고 가능한 모든 mongoid 버전을 안전하게 제거 할 수있는 솔루션을 찾고 있습니다. 내가 말할 수있는 것에서, Mongoid는 버전을 단지 versions이라는 배열 속성에 저장합니다. 데이터베이스를 완전히 사용할 수 없게 만드는 방식으로 내 모든 문서에서 디스크를 가져올 수있는 방법이 있다면 (전체 디스크 스캔 + 쓰기/업데이트를 수행하는 동안 성능면에서) 유용 할 것입니다.MongoDB/Mongoid, 문서 버전 제거하기

답변

1

이 상황을 처리하는 데는 여러 가지 방법이 있습니다. 나는 이것을 두 가지 방법으로 시도해 보았으며, 만 건의 레코드를 시험하기 위해 유사한 처리 시간을 가졌다. 나는 다른 것을 시도해 보았고 훨씬 더 나 빠졌다. 도움이 될 수 있도록 여기에 첨부 해 드리겠습니다.

여기서는 프로세스를 일괄 처리하면 데이터베이스에 미치는 영향을 완화하는 데 도움이된다는 가설을 세우고 있습니다.

첫 번째 방법은 일괄 처리를 처리 할 수있는 한도로 컬렉션에서 찾기를 수행하는 것입니다.

var batchsize = 50 
var c = db.collection.count() 
for(x=0;x<Math.floor(c/batchsize);x++){ 
    db.collection.find({versions: {$exists:true}}).limit(batchsize).forEach(function(cur){ 
     db.collection.update({_id:cur._id},{$unset:{versions:""}}) 
    }) 
} 

여기에 문제는 모든 새로운 일괄 처리에 필요할 수집 스캔입니다. 이 제한은 영향에 도움이되지만 컬렉션에는 여전히 많은 비용이 듭니다.

var arr = db.collection.find({versions:{$exists:true}},{_id:1}).toArray() 
while(arr.length>0){ 
    for(x=0;x<batchsize;x++){ 
     var curId = arr.pop(); 
     db.collection.update(curId,{$unset:{versions:""}}) 
    } 
} 

이 초기 전체 컬렉션 검색을 의미한다 :

번째 방법은 다음에, versions 어레이가 모든 문서의 _id S 배열을 작성 어레이 업데이트를 반복하는 것 그러나이 시점 이후에 배열을 반복하고 일괄 적으로 업데이트합니다.

나는 이전의 것보다 큰 _id을 찾고 업데이트하면서 세 번째 방법을 시도했지만 더 많은 비용이 드는 것으로 나타났습니다 (심지어 _id에 색인을 사용할 수 있었음에도 불구하고) . 유용 할 경우에 대비하여 여기에 추가 할 것입니다.

var curid = db.collection.find({_id:{$gt:MinKey}},{_id:1}).sort({_id:1}).limit(1).next()._id; 
while(curid < MaxKey){ 
    db.collection.update({_id:curid},{$unset:{versions:""}}); 
    curid = db.collection.find({_id:{$gt:curid}},{_id:1}).sort({_id:1}).limit(1).next()._id; 
}