MongoDB에서 배열 안에 포함된 중첩(nested) 문서의 특정 필드를 수정하려면 위치 연산자($)를 사용하면 됩니다. 위치 연산자는 쿼리 조건에 일치하는 첫 번째 배열 요소를 자동으로 식별하여, 해당 요소만 정확하게 업데이트할 수 있도록 도와줍니다.
이 글에서는 실제 예제를 통해 중첩 문서를 업데이트하는 전체 과정을 단계별로 살펴보겠습니다.
1단계: 샘플 컬렉션 생성
먼저 배열 형태의 중첩 문서를 포함하는 컬렉션을 생성합니다. insertOne() 메서드를 사용하여 demo595라는 컬렉션을 만들어 보겠습니다.
> db.demo595.insertOne({
"Information": [
{ "_id": new ObjectId(), "Name": "Chris" },
{ "_id": new ObjectId(), "Name": "Robert" }
]
});
{
"acknowledged" : true,
"insertedId" : ObjectId("5e93369cfd2d90c177b5bce4")
}컬렉션이 성공적으로 생성되었으며, 삽입된 문서의 ObjectId가 반환되었습니다.
2단계: 저장된 문서 확인
find() 메서드를 사용하여 컬렉션에 저장된 모든 문서를 조회합니다.
> db.demo595.find().pretty();
실행 결과는 다음과 같습니다.
{
"_id" : ObjectId("5e93369cfd2d90c177b5bce4"),
"Information" : [
{
"_id" : ObjectId("5e93369cfd2d90c177b5bce2"),
"Name" : "Chris"
},
{
"_id" : ObjectId("5e93369cfd2d90c177b5bce3"),
"Name" : "Robert"
}
]
}Information 필드는 두 개의 하위 문서를 담고 있는 배열입니다. 각 하위 문서는 고유한 ObjectId와 이름 값을 가지고 있습니다.
3단계: 중첩 문서 업데이트
이제 배열 내 특정 하위 문서의 Name 값을 변경해 보겠습니다. ObjectId가 5e93369cfd2d90c177b5bce2인 문서(현재 값: "Chris")의 이름을 "David Miller"로 수정합니다.
여기서 핵심은 위치 연산자($)입니다. 쿼리 조건("Information._id": ObjectId(...))으로 매칭된 배열 요소를 $ 기호가 가리키며, $set 연산자와 함께 사용하면 해당 요소의 필드만 선택적으로 변경됩니다.
> db.demo595.update(
{ "Information._id": ObjectId("5e93369cfd2d90c177b5bce2") },
{ $set: { "Information.$.Name": "David Miller" } }
);
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })결과를 보면 nMatched: 1(조건에 일치한 문서 1개), nModified: 1(실제로 수정된 문서 1개)로, 업데이트가 정상적으로 수행되었음을 알 수 있습니다.
4단계: 업데이트 결과 검증
다시 한번 find() 메서드로 문서를 조회하여 변경 사항을 확인합니다.
> db.demo595.find().pretty();
출력 결과는 다음과 같습니다.
{
"_id" : ObjectId("5e93369cfd2d90c177b5bce4"),
"Information" : [
{
"_id" : ObjectId("5e93369cfd2d90c177b5bce2"),
"Name" : "David Miller"
},
{
"_id" : ObjectId("5e93369cfd2d90c177b5bce3"),
"Name" : "Robert"
}
]
}첫 번째 하위 문서의 이름이 "Chris"에서 "David Miller"로 성공적으로 변경된 것을 확인할 수 있습니다. 나머지 문서는 그대로 유지됩니다.
정리 및 참고 사항
- 위치 연산자($)는 반드시 쿼리 조건 부분에 해당 배열 필드가 포함되어 있어야 정상 동작합니다.
- 배열 내 여러 요소를 한 번에 수정하려면 MongoDB 3.6 이상에서 제공하는 all positional operator($[]) 또는 $[identifier] 연산자를 활용할 수 있습니다.
- 최신 버전의 MongoDB에서는
updateOne(),updateMany()같은 새로운 업데이트 메서드 사용이 권장됩니다.
이처럼 위치 연산자를 활용하면 배열 속 특정 중첩 문서만 정확하고 효율적으로 업데이트할 수 있습니다.