MongoDB - 컬렉션의 모든 레코드를 업데이트하는 가장 빠른 방법은 무엇입니까?
저는 9백만 장의 레코드가 있는 컬렉션을 가지고 있습니다.현재 전체 컬렉션을 업데이트하기 위해 다음 스크립트를 사용하고 있습니다.
simple_update.제이에스
db.mydata.find().forEach(function(data) {
db.mydata.update({_id:data._id},{$set:{pid:(2571 - data.Y + (data.X * 2572))}});
});
이 작업은 명령줄에서 다음과 같이 실행됩니다.
mongo my_test simple_update.js
그래서 제가 하는 일은 간단한 계산을 바탕으로 새로운 필드 pid를 추가하는 것입니다.
더 빠른 방법이 있습니까?이 작업에는 상당한 시간이 걸립니다.
당신이 할 수 있는 일은 두 가지가 있습니다.
이 링크에는 다음과 같은 권장 사항도 포함되어 있습니다.
이것은 일괄 관리 작업을 수행하는 데 좋은 기술입니다.로컬 호스트 인터페이스를 통해 연결하는 서버에서 mongo를 실행합니다.그러면 연결이 매우 빠르고 대기 시간이 짧습니다.db.eval()이 다른 작업을 차단하기 때문에 db.eval()보다 편리합니다.
이것이 아마도 가장 빠를 것입니다.한 대의 서버에서 9M 업데이트를 실행하는 것은 엄청난 작업이 될 것이라는 것을 알아야 합니다.초당 3,000개의 업데이트를 받을 수 있다고 가정해 보겠습니다. 여전히 거의 한 시간 동안 실행할 수 있습니다.
그리고 그것은 실제로 "몽고 문제"가 아니라 하드웨어 제한이 될 것입니다.
db.collection.update 메서드를 사용하고 있습니다.
// db.collection.update( criteria, objNew, upsert, multi ) // --> for reference
db.collection.update( { "_id" : { $exists : true } }, objNew, upsert, true);
더 큰 데이터 집합에는 {multi:true}을(를) 사용하지 않는 것이 좋습니다. 구성 가능성이 낮기 때문입니다.
대량 삽입을 사용하는 더 나은 방법.
대량 작업은 스케줄러 작업에 매우 유용합니다.매일 6개월이 지난 데이터를 삭제해야 한다고 가정합니다.대량 작업을 사용합니다.속도가 빠르고 서버 속도가 느려지지 않습니다.CPU, 메모리 사용량은 10억 개 이상의 문서를 삽입, 삭제 또는 업데이트할 때 눈에 띄지 않습니다.백만 개 이상의 문서를 처리할 때 {multi:true}이(가) 서버 속도를 늦추는 것을 발견했습니다(이에 대한 추가 연구가 필요함).
아래 샘플을 참조하십시오.JS 셸 스크립트입니다. 서버에서 노드 프로그램으로도 실행할 수 있습니다.(이를 위해 npm module shelljs 또는 유사한 것을 사용)
mongo를 3.2+로 업데이트
여러 개의 고유 문서를 업데이트하는 일반적인 방법은 다음과 같습니다.
let counter = 0;
db.myCol.find({}).sort({$natural:1}).limit(1000000).forEach(function(document){
counter++;
document.test_value = "just testing" + counter
db.myCol.save(document)
});
제가 시도했을 때 310-315초가 걸렸습니다.백만 개의 문서를 업데이트하는 데 5분 이상 걸립니다.
제 컬렉션에는 1억 개 이상의 문서가 포함되어 있기 때문에 속도가 다를 수 있습니다.
대량 삽입을 사용하는 것과 동일합니다.
let counter = 0;
// magic no.- depends on your hardware and document size. - my document size is around 1.5kb-2kb
// performance reduces when this limit is not in 1500-2500 range.
// try different range and find fastest bulk limit for your document size or take an average.
let limitNo = 2222;
let bulk = db.myCol.initializeUnorderedBulkOp();
let noOfDocsToProcess = 1000000;
db.myCol.find({}).sort({$natural:1}).limit(noOfDocsToProcess).forEach(function(document){
counter++;
noOfDocsToProcess --;
limitNo--;
bulk.find({_id:document._id}).update({$set:{test_value : "just testing .. " + counter}});
if(limitNo === 0 || noOfDocsToProcess === 0){
bulk.execute();
bulk = db.myCol.initializeUnorderedBulkOp();
limitNo = 2222;
}
});
최고의 시간은 8972 밀리였습니다.그래서 평균적으로 백만 개의 문서를 업데이트하는 데 10초밖에 걸리지 않았습니다.예전 방식보다 30배 더 빠릅니다.
.js 파일에 코드를 넣고 mongo 셸 스크립트로 실행합니다.
누군가 더 좋은 방법을 찾았으면 업데이트해 주세요.몽고를 좀 더 빨리 사용해 보겠습니다.
하는 중Mongo 4.2
에서는db.collection.update()
집계 파이프라인을 허용하여 다른 필드를 기반으로 필드를 업데이트/생성할 수 있으므로 다음과 같은 쿼리 서버 측을 완전히 적용할 수 있습니다.
// { Y: 456, X: 3 }
// { Y: 3452, X: 2 }
db.collection.update(
{},
[{ $set: { pid: {
$sum: [ 2571, { $multiply: [ -1, "$Y" ] }, { $multiply: [ 2572, "$X" ] } ]
}}}],
{ multi: true }
)
// { Y: 456, X: 3, pid: 9831 }
// { Y: 3452, X: 2, pid: 4263 }
번째 파트는 첫번파트째
{}
업데이트할 문서(이 경우 모든 문서)를 필터링하는 일치 쿼리입니다.부분 제2부
[{ $set: { pid: ... } }]
업데이트 집계 파이프라인입니다(집계 파이프라인 사용을 나타내는 대괄호 참조).$set
의 새 집계 연산자 및 별칭입니다.$addFields
방법에 주목pid
는 의값 기으생직다니의 값을 됩니다.X
($X
및 ) 및Y
($Y
) 같은 문서에서.{ multi: true }
그렇지 않으면 첫 번째 일치 문서만 업데이트됩니다.
더 빠를지는 모르겠지만 다중 업데이트를 할 수 있습니다.그냥 말해요update where _id > 0
(이것은 모든 개체에 대해 사실입니다) 그런 다음 '다중' 플래그를 true로 설정하면 전체 컬렉션을 반복할 필요 없이 동일하게 됩니다.
확인: MongoDB - 서버 사이드 코드 실행
언급URL : https://stackoverflow.com/questions/4146452/mongodb-what-is-the-fastest-way-to-update-all-records-in-a-collection
'programing' 카테고리의 다른 글
Microsoft로 인해 버전 충돌이 발생했습니다.NET.Sdk.기능들 (0) | 2023.05.01 |
---|---|
현재 메소드를 호출한 메소드를 어떻게 찾을 수 있습니까? (0) | 2023.05.01 |
WPF의 이미지 컨트롤을 사용하여 시스템을 표시합니다.그림그리기.비트맵 (0) | 2023.05.01 |
Azure 가상 시스템의 도메인 컨트롤러로 사용되는 Azure Active Directory (0) | 2023.05.01 |
Android Studio 프로젝트 구조(v.s. Eclipse 프로젝트 구조) (0) | 2023.05.01 |