MongoDB에서 단일 쿼리로 여러 행 업데이트하기
여러 문서를 한 번의 작업으로 수정하려면 initializeUnorderedBulkOp() 메서드를 활용한 벌크(Bulk) 연산을 사용하는 것이 가장 효율적입니다. 벌크 연산은 여러 업데이트 명령을 하나의 배치(batch)로 묶어 서버에 한 번에 전송하므로, 개별적으로 쿼리를 실행할 때보다 네트워크 오버헤드가 줄어들고 처리 속도가 크게 향상됩니다.
1단계: 샘플 컬렉션 생성
먼저 실습에 사용할 문서들이 담긴 컬렉션을 만들어 보겠습니다.
> db.upDateMultipleRowsDemo.insertOne({"CustomerName":"John","CustomerPurchaseAmount":500});
{
"acknowledged" : true,
"insertedId" : ObjectId("5cd6ceb06d78f205348bc626")
}
> db.upDateMultipleRowsDemo.insertOne({"CustomerName":"Chris","CustomerPurchaseAmount":700});
{
"acknowledged" : true,
"insertedId" : ObjectId("5cd6ceb26d78f205348bc627")
}
> db.upDateMultipleRowsDemo.insertOne({"CustomerName":"David","CustomerPurchaseAmount":50});
{
"acknowledged" : true,
"insertedId" : ObjectId("5cd6ceb36d78f205348bc628")
}
> db.upDateMultipleRowsDemo.insertOne({"CustomerName":"Larry","CustomerPurchaseAmount":1900});
{
"acknowledged" : true,
"insertedId" : ObjectId("5cd6ceb46d78f205348bc629")
}
2단계: 현재 저장된 문서 확인
find() 메서드를 사용하면 컬렉션의 모든 문서를 조회할 수 있습니다.
> db.upDateMultipleRowsDemo.find().pretty();
위 쿼리를 실행하면 다음과 같은 결과가 출력됩니다.
{
"_id" : ObjectId("5cd6ceb06d78f205348bc626"),
"CustomerName" : "John",
"CustomerPurchaseAmount" : 500
}
{
"_id" : ObjectId("5cd6ceb26d78f205348bc627"),
"CustomerName" : "Chris",
"CustomerPurchaseAmount" : 700
}
{
"_id" : ObjectId("5cd6ceb36d78f205348bc628"),
"CustomerName" : "David",
"CustomerPurchaseAmount" : 50
}
{
"_id" : ObjectId("5cd6ceb46d78f205348bc629"),
"CustomerName" : "Larry",
"CustomerPurchaseAmount" : 1900
}
3단계: 벌크 연산으로 여러 행 한 번에 업데이트
이제 단일 쿼리로 여러 행을 동시에 업데이트해 보겠습니다. initializeUnorderedBulkOp()로 벌크 객체를 초기화한 뒤, 각 문서별로 updateOne() 작업을 추가하고 마지막에 execute()를 호출해 일괄 실행합니다.
> var manyUpdateValue = db.upDateMultipleRowsDemo.initializeUnorderedBulkOp();
> manyUpdateValue.find({ _id: ObjectId("5cd6ceb06d78f205348bc626")}).updateOne({$set:{"CustomerName":"Bob" }});
> manyUpdateValue.find({ _id: ObjectId("5cd6ceb36d78f205348bc628")}).updateOne({$set:{"CustomerPurchaseAmount":56544444}});
> manyUpdateValue.execute();
BulkWriteResult({
"writeErrors" : [ ],
"writeConcernErrors" : [ ],
"nInserted" : 0,
"nUpserted" : 0,
"nMatched" : 2,
"nModified" : 2,
"nRemoved" : 0,
"upserted" : [ ]
})
실행 결과인 BulkWriteResult를 살펴보면 nMatched와 nModified 값이 각각 2로 표시됩니다. 이는 두 개의 문서가 조건과 일치했으며, 두 문서 모두 성공적으로 수정되었음을 의미합니다.
4단계: 업데이트 결과 검증
모든 문서를 다시 한번 조회하여 변경 사항이 올바르게 적용되었는지 확인해 보겠습니다.
> db.upDateMultipleRowsDemo.find().pretty();
실행 결과는 다음과 같습니다.
{
"_id" : ObjectId("5cd6ceb06d78f205348bc626"),
"CustomerName" : "Bob",
"CustomerPurchaseAmount" : 500
}
{
"_id" : ObjectId("5cd6ceb26d78f205348bc627"),
"CustomerName" : "Chris",
"CustomerPurchaseAmount" : 700
}
{
"_id" : ObjectId("5cd6ceb36d78f205348bc628"),
"CustomerName" : "David",
"CustomerPurchaseAmount" : 56544444
}
{
"_id" : ObjectId("5cd6ceb46d78f205348bc629"),
"CustomerName" : "Larry",
"CustomerPurchaseAmount" : 1900
}
첫 번째 문서의 고객 이름이 "John"에서 "Bob"으로 변경되었고, 세 번째 문서의 구매 금액이 50에서 56544444로 업데이트된 것을 확인할 수 있습니다. 나머지 문서는 업데이트 조건에 해당하지 않아 원래 값이 그대로 유지되었습니다.
정리
이처럼 initializeUnorderedBulkOp()를 사용하면 조건이 서로 다른 여러 업데이트 작업도 하나의 쿼리로 묶어 실행할 수 있습니다. 대량의 데이터를 다룰 때 특히 유용하며, unordered 방식은 작업 순서를 보장하지 않는 대신 더 빠른 병렬 처리가 가능합니다. 만약 작업 순서가 중요하다면 initializeOrderedBulkOp()를 사용하면 됩니다.