Computer >> 컴퓨터 >  >> 프로그래밍 >> MongoDB

MongoDB 문서 내 배열 객체 업데이트 방법 - 중첩(Nested) 업데이트 완벽 가이드

MongoDB에서 문서 배열의 객체를 업데이트하는 방법

MongoDB에서 문서(document) 내부에 포함된 배열(array)의 객체를 수정하려면 update() 메서드를 사용해야 합니다. 특히 위치 연산자(positional operator)인 $와 함께 사용하면, 조건에 일치하는 특정 배열 요소만 정확하게 업데이트할 수 있습니다.

update() 메서드의 동작을 이해하기 위해 먼저 샘플 컬렉션과 문서를 생성해 보겠습니다.

1. 테스트용 컬렉션 생성

다음 쿼리는 고객 정보와 아이템 상세 내역을 담은 문서를 삽입합니다.

> db.updateObjects.insertOne({"CustomerId":1,"CustomerName":"Larry","TotalItems":100,
... "ItemDetails":[
... {
... "NameOfItem":"Item_1",
... "Amount":450
... },
... {
... "NameOfItem":"Item_2",
... "Amount":500
... },
... {
... "NameOfItem":"Item_3",
... "Amount":200
... }
... ]
... }
... );

실행 결과는 다음과 같습니다.

{
    "acknowledged" : true,
    "insertedId" : ObjectId("5c6d688b0c3d5054b766a769")
}

2. find() 메서드로 문서 조회

생성된 컬렉션의 문서는 find() 메서드로 확인할 수 있습니다.

> db.updateObjects.find().pretty();

위 쿼리의 출력 결과입니다.

{
    "_id" : ObjectId("5c6d688b0c3d5054b766a769"),
    "CustomerId" : 1,
    "CustomerName" : "Larry",
    "TotalItems" : 100,
    "ItemDetails" : [
        {
            "NameOfItem" : "Item_1",
            "Amount" : 450
        },
        {
            "NameOfItem" : "Item_2",
            "Amount" : 500
        },
        {
            "NameOfItem" : "Item_3",
            "Amount" : 200
        }
    ]
}

3. $inc 연산자와 위치 연산자($)로 중첩 업데이트 수행

이제 NameOfItem"Item_3"인 객체의 Amount 필드(현재 값 200)를 130만큼 증가시켜 보겠습니다. 이때 값의 증감에는 $inc 연산자를 사용하고, 조건에 매칭된 배열 요소를 지정하기 위해 위치 연산자($)를 활용합니다.

> db.updateObjects.update({"CustomerId":1,"ItemDetails.NameOfItem":"Item_3"},
{$inc:{"ItemDetails.$.Amount":130}},
... false,true);
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })

출력 결과에서 nModified : 1이 반환된 것으로 보아 업데이트가 성공적으로 완료되었음을 알 수 있습니다. 여기서 update() 메서드의 세 번째 인자 false는 upsert 비활성화, 네 번째 인자 true는 다중 문서 업데이트(multi) 설정을 의미합니다.

4. 업데이트 결과 확인

수정된 문서를 다시 조회해 보겠습니다.

> db.updateObjects.find().pretty();

업데이트 후의 출력 결과는 다음과 같습니다.

{
    "_id" : ObjectId("5c6d688b0c3d5054b766a769"),
    "CustomerId" : 1,
    "CustomerName" : "Larry",
    "TotalItems" : 100,
    "ItemDetails" : [
        {
            "NameOfItem" : "Item_1",
            "Amount" : 450
        },
        {
            "NameOfItem" : "Item_2",
            "Amount" : 500
        },
        {
            "NameOfItem" : "Item_3",
            "Amount" : 330
        }
    ]
}

결과 분석

위 출력 결과를 보면, 기존에 200이었던 Item_3의 Amount 값이 130만큼 증가하여 330으로 변경된 것을 확인할 수 있습니다. 반면 Item_1(450)과 Item_2(500)는 그대로 유지되었습니다.

핵심은 ItemDetails.$.Amount처럼 위치 연산자 $를 사용하면, 쿼리 조건(ItemDetails.NameOfItem: "Item_3")과 일치하는 첫 번째 배열 요소만 선택적으로 업데이트된다는 점입니다. 이 패턴은 MongoDB에서 중첩된 배열 데이터를 다룰 때 가장 널리 사용되는 기법입니다.