MongoDB에서 중첩 배열(nested array) 내부의 특정 값을 증가시키고 싶다면 위치 연산자 $를 사용하면 됩니다. 이 연산자는 쿼리 조건과 일치하는 첫 번째 배열 요소를 가리키며, $inc 연산자와 함께 사용하면 해당 요소의 필드 값을 손쉽게 증가시킬 수 있습니다.
개념을 명확히 이해하기 위해 실제 예제를 통해 단계별로 살펴보겠습니다.
1단계: 샘플 컬렉션 생성
먼저 학생 정보를 담은 문서로 컬렉션을 생성합니다. 학생 세부 정보(StudentDetails)는 배열 형태로 저장되며, 각 요소는 학생 ID와 점수를 포함합니다.
> db.incrementValueInNestedArrayDemo.insertOne(
... {
... "UniqueId": 1,
... "StudentDetails": [
... { "StudentId": 101, "StudentMarks": 97 },
... { "StudentId": 103, "StudentMarks": 99 },
... { "StudentId": 105, "StudentMarks": 69 },
... { "StudentId": 107, "StudentMarks": 59 }
... ]
... }
... );
{
"acknowledged" : true,
"insertedId" : ObjectId("5c77dd71fc4e719b197a12f7")
}2단계: 저장된 문서 확인
find() 메서드를 사용해 컬렉션의 모든 문서를 조회합니다.
> db.incrementValueInNestedArrayDemo.find().pretty();
실행 결과는 다음과 같습니다.
{
"_id" : ObjectId("5c77dd71fc4e719b197a12f7"),
"UniqueId" : 1,
"StudentDetails" : [
{
"StudentId" : 101,
"StudentMarks" : 97
},
{
"StudentId" : 103,
"StudentMarks" : 99
},
{
"StudentId" : 105,
"StudentMarks" : 69
},
{
"StudentId" : 107,
"StudentMarks" : 59
}
]
}3단계: 위치 연산자 $로 값 증가시키기
이제 중첩 배열 내부의 값을 증가시키는 핵심 쿼리입니다. StudentId가 107인 학생의 점수를 1만큼 올려보겠습니다.
> db.incrementValueInNestedArrayDemo.update(
{ UniqueId: 1, "StudentDetails.StudentId": 107 },
{ $inc: { "StudentDetails.$.StudentMarks": 1 } }
);
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })여기서 주목할 부분은 두 가지입니다.
- 쿼리 조건:
"StudentDetails.StudentId": 107처럼 배열 내부의 필드 경로를 지정하여 대상 요소를 찾습니다. - $inc와 $의 조합:
"StudentDetails.$.StudentMarks"에서 $ 위치 연산자가 조건에 일치한 배열 요소의 인덱스를 자동으로 참조합니다.
4단계: 업데이트 결과 검증
다시 find() 메서드를 실행해 StudentId 107의 점수가 실제로 증가했는지 확인합니다.
> db.incrementValueInNestedArrayDemo.find().pretty();
실행 결과는 다음과 같습니다.
{
"_id" : ObjectId("5c77dd71fc4e719b197a12f7"),
"UniqueId" : 1,
"StudentDetails" : [
{
"StudentId" : 101,
"StudentMarks" : 97
},
{
"StudentId" : 103,
"StudentMarks" : 99
},
{
"StudentId" : 105,
"StudentMarks" : 69
},
{
"StudentId" : 107,
"StudentMarks" : 60
}
]
}결과 분석
출력 결과를 보면 StudentId 107인 학생의 StudentMarks 필드가 59에서 60으로 변경된 것을 확인할 수 있습니다. 즉, 정확히 1만큼 증가했습니다. 나머지 학생들의 점수는 그대로 유지되었으며, 조건에 일치한 배열 요소만 선택적으로 수정된 것을 알 수 있습니다.
정리
중첩 배열 내부의 값을 증가시키는 방법을 요약하면 다음과 같습니다.
- update() 쿼리 조건에서 배열 내부 필드(예:
"StudentDetails.StudentId": 107)로 대상 요소를 특정합니다. - 업데이트 연산자로
$inc를 사용하고, 필드 경로에 위치 연산자$(예:"StudentDetails.$.StudentMarks")를 넣어 일치한 요소만 수정합니다. - 증가시키고 싶은 값만큼 숫자를 지정합니다(음수를 입력하면 감소).
이 패턴은 배열 안에 여러 하위 문서가 있을 때 특정 요소만 효율적으로 갱신해야 하는 상황에서 매우 유용하게 활용됩니다.