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

대규모 MongoDB 컬렉션의 모든 문서에 새 속성 추가하는 방법

대규모 MongoDB 컬렉션의 모든 문서에 새로운 속성(필드)을 추가해야 하는 경우가 종종 있습니다. 이럴 때 update 명령어와 forEach() 메서드를 함께 사용하면 컬렉션을 순회하며 각 문서를 효율적으로 업데이트할 수 있습니다. 이 글에서는 실제 예제를 통해 단계별로 과정을 살펴보겠습니다.

1. 샘플 컬렉션 생성하기

먼저 예제로 사용할 컬렉션을 생성하고 문서를 삽입합니다.

> db.addingNewPropertyDemo.insertOne({"StudentName":"John","StudentAge":23,"CountryName":"US"});
{
    "acknowledged" : true,
    "insertedId" : ObjectId("5ca1e61866324ffac2a7dc56")
}
> db.addingNewPropertyDemo.insertOne({"StudentName":"David","StudentAge":21,"CountryName":"AUS"});
{
    "acknowledged" : true,
    "insertedId" : ObjectId("5ca1e62366324ffac2a7dc57")
}
> db.addingNewPropertyDemo.insertOne({"StudentName":"Bob","StudentAge":21,"CountryName":"UK"});
{
    "acknowledged" : true,
    "insertedId" : ObjectId("5ca1e62d66324ffac2a7dc58")
}

위 코드는 학생 이름, 나이, 국가 정보를 담은 세 개의 문서를 addingNewPropertyDemo 컬렉션에 순차적으로 삽입합니다.

2. 전체 문서 조회하기

find() 메서드를 사용하면 컬렉션에 저장된 모든 문서를 확인할 수 있습니다.

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

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

{
    "_id" : ObjectId("5ca1e61866324ffac2a7dc56"),
    "StudentName" : "John",
    "StudentAge" : 23,
    "CountryName" : "US"
}
{
    "_id" : ObjectId("5ca1e62366324ffac2a7dc57"),
    "StudentName" : "David",
    "StudentAge" : 21,
    "CountryName" : "AUS"
}
{
    "_id" : ObjectId("5ca1e62d66324ffac2a7dc58"),
    "StudentName" : "Bob",
    "StudentAge" : 21,
    "CountryName" : "UK"
}

3. forEach()로 각 문서에 새 속성 추가하기

이제 핵심 단계입니다. forEach()로 컬렉션의 모든 문서를 하나씩 순회하면서, 각 문서의 _id를 기준으로 $set 연산자를 이용해 새 속성을 추가합니다. 여기서는 학생 이름을 대문자로 변환한 값을 담는 StudentNameInUpperCase 필드를 새로 만들어 보겠습니다.

> db.addingNewPropertyDemo.find().forEach(function(data){
    db.addingNewPropertyDemo.update(
        { _id: data._id },
        { $set: { StudentNameInUpperCase: data.StudentName.toUpperCase() } }
    )
});

이 쿼리의 동작 방식은 다음과 같습니다.

  • find()가 컬렉션의 모든 문서를 가져옵니다.
  • forEach()가 각 문서를 순서대로 처리합니다.
  • 각 문서의 _id로 해당 문서를 찾아 $set으로 새 필드를 추가합니다.

4. 결과 확인하기

새 속성이 정상적으로 추가되었는지 다시 한번 전체 문서를 조회해 보겠습니다.

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

새 속성이 함께 출력되는 것을 확인할 수 있습니다.

{
    "_id" : ObjectId("5ca1e61866324ffac2a7dc56"),
    "StudentName" : "John",
    "StudentAge" : 23,
    "CountryName" : "US",
    "StudentNameInUpperCase" : "JOHN"
}
{
    "_id" : ObjectId("5ca1e62366324ffac2a7dc57"),
    "StudentName" : "David",
    "StudentAge" : 21,
    "CountryName" : "AUS",
    "StudentNameInUpperCase" : "DAVID"
}
{
    "_id" : ObjectId("5ca1e62d66324ffac2a7dc58"),
    "StudentName" : "Bob",
    "StudentAge" : 21,
    "CountryName" : "UK",
    "StudentNameInUpperCase" : "BOB"
}

출력 결과를 보면 세 개의 문서 모두에 StudentNameInUpperCase 속성이 성공적으로 추가된 것을 확인할 수 있습니다.

참고: 더 효율적인 대안들

forEach() 방식은 각 문서마다 개별적으로 업데이트를 수행하기 때문에 문서 수가 매우 많으면 시간이 오래 걸릴 수 있습니다. 상황에 따라 아래 방법을 고려해 보세요.

  • updateMany(): 모든 문서에 동일한 값의 필드를 추가하는 경우라면 db.collection.updateMany({}, { $set: { newField: value } })처럼 한 번의 호출로 처리할 수 있어 훨씬 빠릅니다.
  • bulkWrite(): 문서마다 다른 값을 넣어야 하는 경우에는 여러 업데이트 작업을 하나의 배치로 묶어 실행하는 bulkWrite()를 사용하면 네트워크 왕복 횟수를 크게 줄일 수 있습니다.

다만 위 예제처럼 기존 필드 값을 가공(예: 문자열을 대문자로 변환)해서 새 필드를 만들어야 한다면, 서버 측 JavaScript 실행이 필요하므로 forEach()를 활용한 방식이 유용합니다.