2016-06-23 2 views
3

1 억개 이상의 mongodb 문서에 새로운 필드를 추가하는 가장 빠르고 안전한 전략은 무엇입니까? 3 노드 복제본에 MongoDB를 3.0 사용mongodb의 1 억 레코드에 새로운 필드 추가하기

배경

  • 설정
  • 우리는 현재 문서의 다른 필드 (post_time)의 데이터에 기초하는 새로운 필드 (post_hour)를 추가 . post_hour 필드는 post_time을 시간으로 절단 한 버전입니다.

답변

0

나는 약 2500 만 건의 문서를 업데이트하는 스크립트를 작성했고 모든 문서를 업데이트하는 데 많은 시간이 걸렸다. 성능을 향상시키기 위해 업데이트 된 문서를 새 컬렉션에 삽입하고 새 컬렉션의 이름을 바꿨습니다.이 방법은 문서를 업데이트하는 대신 삽입하여 ('삽입'작업이 '업데이트'작업보다 빠르기 때문에) 도움이되었습니다.

위의 기록 된 스크립트가 실행 얻을 것이다
/*This method returns postHour*/ 
function convertPostTimeToPostHour(postTime){ 
} 

var totalCount = db.person.count(); 
var chunkSize = 1000; 
var chunkCount = totalCount/chunkSize; 
offset = 0; 
for(index = 0; index<chunkCount; index++){ 
    personList = db.persons.find().skip(offset).limit(chunkSize); 
    personList.forEach(function (person) { 
     newPerson = person; 
     newPerson.post_hour = convertPostTimeToPostHour(person.post_time); 
     db.personsNew.insert(newPerson); // This will insert the record in a new collection 
    }); 
    offset += chunkSize; 
} 

, 새 컬렉션 'personNew는'필드의 값으로 업데이트 된 기록이있을 것이다 'post_hour : 여기

샘플 스크립트 (내가 그것을 테스트하지 않았습니다)입니다 '설정.

기존 컬렉션에 인덱스가있는 경우 새 컬렉션에서 다시 만들어야합니다.

인덱스가 생성되면 'person'컬렉션의 이름을 'personOld'로, 'personNew'를 'person'으로 바꿀 수 있습니다.

+0

다른 쉘에서 각 청크를 수행하는 것이 속도 성능을 향상시킬 수 있다고 생각합니다. –

-1

snapshot (우리는 크기를 확장하는 것처럼) 쿼리 결과에서 중복을 방지 할 수 있습니다 - 어떤 문제가 발생하면 제거 할 수 있습니다.

'A1'은 모음의 이름입니다 아래 몽고의 쉘 스크립트를 찾아주세요 :

var documentLimit = 1000; 

var docCount = db.a1.find({ 
     post_hour : { 
      $exists : false 
     } 
    }).count(); 

var chunks = docCount/documentLimit; 

for (var i = 0; i <= chunks; i++) { 
    db.a1.find({ 
     post_hour : { 
      $exists : false 
     } 
    }).snapshot() 
     .limit(documentLimit) 
     .forEach(function (doc) { 
     doc.post_hour = 12; // put your transformation here 
     // db.a1.save(doc); // uncomment this line to save data 
          // you can also specify write concern here 
     printjson(doc);  // comment this line to avoid polution of shell output 
          // this is just for test purposes  
    }); 
} 

당신은 매개 변수를 사용하여 재생할 수 있지만, 대부분이 1000 개 개의 레코드 블록에서 실행되는 한, 즉 최적 보인다.