MongoDB에서 $set 연산자를 사용하면 도큐먼트 내부에 중첩된 필드나 임베디드(내장) 문서의 특정 값만 손쉽게 수정할 수 있습니다. 이 글에서는 기본 문법부터 실제 예제까지 단계별로 살펴보겠습니다.
기본 문법
중첩된 값을 업데이트할 때는 외부 필드 이름과 내부 필드 이름을 점(.)으로 연결한 경로를 사용합니다.
db.yourCollectionName.update({ }, { $set: { "yourOuterFieldName.yourInnerFieldName": "yourValue" } });여기서 쿼리 조건 부분을 비워 두면({ }) 컬렉션의 첫 번째 도큐먼트가 대상이 됩니다. 실무에서는 특정 조건을 지정해 원하는 도큐먼트만 정확히 업데이트하는 것이 좋습니다.
예제용 컬렉션 생성하기
문법을 이해하기 위해 먼저 샘플 도큐먼트가 포함된 컬렉션을 생성해 보겠습니다.
> db.updateNestedValueDemo.insertOne({"CustomerName":"Chris",
... "CustomerDetails":{"CustomerAge":25,"CustomerCompanyName":"Google","CustomerCityName":"US"}});
{
"acknowledged" : true,
"insertedId" : ObjectId("5c8fccc4d3c9d04998abf015")
}생성된 데이터 확인
find() 메서드를 사용하면 컬렉션의 모든 도큐먼트를 조회할 수 있습니다.
> db.updateNestedValueDemo.find().pretty();
실행 결과는 다음과 같습니다.
{
"_id" : ObjectId("5c8fccc4d3c9d04998abf015"),
"CustomerName" : "Chris",
"CustomerDetails" : {
"CustomerAge" : 25,
"CustomerCompanyName" : "Google",
"CustomerCityName" : "US"
}
}$set으로 중첩된 값 업데이트하기
이제 $set을 사용하여 임베디드 문서 안의 CustomerCompanyName 필드를 변경해 보겠습니다. 바깥 필드인 CustomerDetails와 안쪽 필드를 점 표기법으로 연결한다는 점이 핵심입니다.
> db.updateNestedValueDemo.update({ }, { $set: { "CustomerDetails.CustomerCompanyName": "Dell" } });
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })WriteResult를 보면 1개의 도큐먼트가 매칭되고(nMatched: 1), 1개의 필드가 실제로 수정되었음(nModified: 1)을 확인할 수 있습니다.
업데이트 결과 검증
다시 find() 메서드로 데이터를 조회해 변경 사항을 확인합니다.
> db.updateNestedValueDemo.find().pretty();
실행 결과는 다음과 같습니다.
{
"_id" : ObjectId("5c8fccc4d3c9d04998abf015"),
"CustomerName" : "Chris",
"CustomerDetails" : {
"CustomerAge" : 25,
"CustomerCompanyName" : "Dell",
"CustomerCityName" : "US"
}
}위 출력 결과를 보면 중첩된 필드인 CustomerCompanyName의 값이 Google에서 Dell로 성공적으로 변경된 것을 알 수 있습니다. 다른 중첩 필드들(CustomerAge, CustomerCityName)은 그대로 유지됩니다.
정리 및 참고 사항
- 중첩 필드를 업데이트할 때는
"외부필드.내부필드"형태의 점 표기법(dot notation)을 사용합니다. - $set은 지정한 필드만 수정하고 나머지 구조는 그대로 유지하므로, 전체 임베디드 문서를 교체하는 것보다 안전합니다.
- 최신 MongoDB 버전(4.2 이상)에서는
update()대신updateOne(),updateMany()사용이 권장됩니다. - 배열 안의 중첩 요소를 수정할 때는 위치 연산자($, $[])와 함께 활용할 수 있습니다.