MongoDB에서 배열의 특정 위치(요소) 필드를 업데이트하는 방법
MongoDB에서는 위치 연산자($)를 활용하면 문서 배열 내부에 중첩된 배열의 특정 인덱스에 해당하는 값을 직접 수정할 수 있습니다. 배열 전체를 교체하지 않고도 원하는 위치의 값만 간단히 변경할 수 있어 매우 유용합니다. 아래에서 기본 문법과 실습 예제를 단계별로 살펴보겠습니다.
기본 문법
배열의 특정 요소를 업데이트할 때 사용하는 기본 문법은 다음과 같습니다:
{"yourArrayDocumentName.$.yourNestedArrayDocument.yourPosition":"yourValue"}});여기서 $는 쿼리 조건과 일치하는 첫 번째 배열 요소를 가리키는 위치 연산자이며, yourPosition 자리에 원하는 인덱스 번호를 지정하면 됩니다.
예제 데이터 준비: 컬렉션 생성
문법을 제대로 이해하기 위해 배우 정보를 담은 컬렉션을 먼저 만들어 보겠습니다. 다음 쿼리로 updateExactField 컬렉션에 문서를 삽입합니다:
> db.updateExactField.insertOne({"ActorId":1,"ActorDetails":[{"ActorName":"Johnny Depp","MovieList":["The Tourist","Public Enemy"]},
... {"ActorName":"Chris Evans","MovieList":["Captain America","Avengers"]}]});
{
"acknowledged" : true,
"insertedId" : ObjectId("5c6d7f63f2db199c1278e7f1")
}find() 메서드를 사용해 저장된 문서를 확인할 수 있습니다:
> db.updateExactField.find().pretty();
실행 결과는 다음과 같습니다:
{
"_id" : ObjectId("5c6d7f63f2db199c1278e7f1"),
"ActorId" : 1,
"ActorDetails" : [
{
"ActorName" : "Johnny Depp",
"MovieList" : [
"The Tourist",
"Public Enemy"
]
},
{
"ActorName" : "Chris Evans",
"MovieList" : [
"Captain America",
"Avengers"
]
}
]
}사례 1: 세 번째 위치(인덱스 2)의 값 업데이트
첫 번째 사례에서는 Chris Evans의 영화 목록(MovieList)에서 세 번째 위치, 즉 인덱스 2(배열은 0부터 시작하므로)의 값을 업데이트해 보겠습니다. 쿼리는 다음과 같습니다:
> db.updateExactField.update(
... {"ActorDetails.ActorName":"Chris Evans"},
... {$set:
... {"ActorDetails.$.MovieList.2":"Avengers:Infinity War"}});
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })업데이트 후 다시 find()로 문서를 조회해 결과를 확인합니다:
> db.updateExactField.find().pretty();
실행 결과:
{
"_id" : ObjectId("5c6d7f63f2db199c1278e7f1"),
"ActorId" : 1,
"ActorDetails" : [
{
"ActorName" : "Johnny Depp",
"MovieList" : [
"The Tourist",
"Public Enemy"
]
},
{
"ActorName" : "Chris Evans",
"MovieList" : [
"Captain America",
"Avengers",
"Avengers:Infinity War"
]
}
]
}위 출력 결과를 보면 "Avengers:Infinity War"가 세 번째 위치, 즉 인덱스 2에 추가된 것을 확인할 수 있습니다.
사례 2: 두 번째 위치(인덱스 1)의 값 업데이트
이번에는 두 번째 위치, 즉 인덱스 1의 값을 업데이트해 보겠습니다. 쿼리는 다음과 같습니다:
> db.updateExactField.update( {"ActorDetails.ActorName":"Chris Evans"}, {$set:
{"ActorDetails.$.MovieList.1":"Gifted"}});
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })find() 메서드로 변경된 문서를 다시 확인합니다:
> db.updateExactField.find().pretty();
실행 결과:
{
"_id" : ObjectId("5c6d7f63f2db199c1278e7f1"),
"ActorId" : 1,
"ActorDetails" : [
{
"ActorName" : "Johnny Depp",
"MovieList" : [
"The Tourist",
"Public Enemy"
]
},
{
"ActorName" : "Chris Evans",
"MovieList" : [
"Captain America",
"Gifted",
"Avengers:Infinity War"
]
}
]
}최종 출력 결과를 보면 "Gifted"가 두 번째 위치, 즉 인덱스 1에 반영된 것을 알 수 있습니다.
정리
이처럼 MongoDB에서는 $set 연산자와 $ 위치 연산자, 그리고 인덱스 번호를 조합하면 배열 전체를 재작성하지 않고도 중첩 배열의 특정 위치에 있는 값을 손쉽게 업데이트할 수 있습니다. 참고로 최신 MongoDB 버전에서는 updateOne(), updateMany() 메서드 사용이 권장되며, 위치 연산자를 활용한 업데이트 방식은 동일하게 적용됩니다.