개요
MongoDB에서 수식(연산식)을 활용해 컬렉션 내 문서의 각 필드를 한 번에 업데이트하려면 update() 메서드와 $mul 연산자, 그리고 배열 전체 위치(all positional) 연산자인 $[]를 함께 사용하면 됩니다. 먼저 예제로 사용할 컬렉션을 생성해 보겠습니다.
1. 샘플 데이터 삽입
> db.demo749.insertOne({"details":[{"id":1,a:10},{"id":2,a:5},{"id":3,a:20}]});
{
"acknowledged" : true,
"insertedId" : ObjectId("5eae6fb0a930c785c834e565")
}2. 현재 문서 확인
find() 메서드를 사용해 컬렉션의 모든 문서를 조회합니다.
> db.demo749.find().pretty();
위 명령을 실행하면 다음과 같은 결과가 출력됩니다.
{
"_id" : ObjectId("5eae6fb0a930c785c834e565"),
"details" : [
{
"id" : 1,
"a" : 10
},
{
"id" : 2,
"a" : 5
},
{
"id" : 3,
"a" : 20
}
]
}3. 수식으로 필드 일괄 업데이트하기
다음은 details 배열의 각 요소에 있는 a 필드 값에 수식(2/5 곱하기)을 적용해 일괄 업데이트하는 쿼리입니다.
> db.demo749.update(
... {
...
... },
... {
... $mul: { "details.$[].a": 2/5}
... },
... { multi:true}
... )
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })여기서 핵심은 "details.$[].a" 표현식입니다. $[]는 배열의 모든 요소를 가리키는 전체 위치 연산자로, details 배열 내 모든 객체의 a 필드에 동일한 수식이 적용됩니다. 또한 { multi: true } 옵션을 지정하면 조건에 일치하는 모든 문서가 한 번에 업데이트됩니다.
4. 업데이트 결과 확인
업데이트 후 다시 find() 메서드로 결과를 조회해 보겠습니다.
> db.demo749.find().pretty();
실행 결과, 각 요소의 a 값이 2/5배(0.4배)로 변경된 것을 확인할 수 있습니다.
{
"_id" : ObjectId("5eae6fb0a930c785c834e565"),
"details" : [
{
"id" : 1,
"a" : 4
},
{
"id" : 2,
"a" : 2
},
{
"id" : 3,
"a" : 8
}
]
}정리
이처럼 MongoDB에서는 $mul 연산자와 $[] 전체 위치 연산자를 조합하면 별도의 반복문 없이도 배열 내 모든 요소의 특정 필드를 하나의 수식으로 손쉽게 일괄 업데이트할 수 있습니다. 참고로 MongoDB 5.0 이상에서는 update() 대신 updateOne(), updateMany() 메서드 사용이 권장되며, 위 예제는 updateMany()로 동일하게 작성할 수 있습니다.