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

MongoDB mapReduce() 함수로 대체 문서만 골라 출력하는 방법

MongoDB에서 mapReduce() 함수를 활용하면 컬렉션에 저장된 문서 중 원하는 조건에 맞는 문서만 골라낼 수 있습니다. 이 글에서는 scope 변수로 문서 순서를 카운트하고, 대체(홀수 번째) 문서만 emit()으로 내보내는 방법을 단계별로 살펴보겠습니다.

1. 샘플 데이터 준비하기

먼저 데모용 컬렉션을 생성하고 문서를 여러 개 삽입합니다.

> db.demo636.insert({id:1});
WriteResult({ "nInserted" : 1 })
> db.demo636.insert({id:2});
WriteResult({ "nInserted" : 1 })
> db.demo636.insert({id:3});
WriteResult({ "nInserted" : 1 })
> db.demo636.insert({id:4});
WriteResult({ "nInserted" : 1 })
> db.demo636.insert({id:5});
WriteResult({ "nInserted" : 1 })
> db.demo636.insert({id:6});
WriteResult({ "nInserted" : 1 })

2. find()로 전체 문서 확인하기

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

> db.demo636.find();

위 명령을 실행하면 다음과 같은 결과가 출력됩니다.

{ "_id" : ObjectId("5e9c127b6c954c74be91e6d2"), "id" : 1 }
{ "_id" : ObjectId("5e9c127e6c954c74be91e6d3"), "id" : 2 }
{ "_id" : ObjectId("5e9c127f6c954c74be91e6d4"), "id" : 3 }
{ "_id" : ObjectId("5e9c12816c954c74be91e6d5"), "id" : 4 }
{ "_id" : ObjectId("5e9c12836c954c74be91e6d6"), "id" : 5 }
{ "_id" : ObjectId("5e9c12896c954c74be91e6d7"), "id" : 6 }

총 6개의 문서가 순서대로 저장되어 있는 것을 확인할 수 있습니다.

3. mapReduce()로 대체 문서만 출력하는 쿼리 작성

다음 쿼리는 map 함수 안에서 scope로 전달받은 카운터(oddCounter)를 문서마다 하나씩 증가시키고, 카운터가 2로 나누어 떨어지지 않을 때만 emit()으로 문서를 내보냅니다. 그 결과 첫 번째, 세 번째, 다섯 번째 문서처럼 하나씩 건너뛰며 출력됩니다.

> db.demo636.mapReduce(
...     function () {
...        oddCounter++;
...        var id = this._id;
...        delete this._id;
...        if ( oddCounter % d != 0 )
...           emit(id, this);
...     },
...     function() {},
...     {
...        "scope": { "oddCounter": 0, "d": 2 },
...        "out": { "inline": 1 }
...     }
... )

4. 실행 결과 확인하기

쿼리를 실행하면 아래와 같이 대체 문서(id가 1, 3, 5인 문서)만 results 배열에 담겨 반환됩니다.

{
    "results" : [
       {
          "_id" : ObjectId("5e9c127b6c954c74be91e6d2"),
          "value" : {
             "id" : 1
          }
       },
       {
          "_id" : ObjectId("5e9c127f6c954c74be91e6d4"),
          "value" : {
             "id" : 3
          }
       },
       {
          "_id" : ObjectId("5e9c12836c954c74be91e6d6"),
          "value" : {
             "id" : 5
          }
       }
    ],
    "timeMillis" : 29,
    "counts" : {
       "input" : 6,
       "emit" : 3,
       "reduce" : 0,
       "output" : 3
    },
    "ok" : 1
}

counts 항목을 보면 input이 6개였지만 emit은 3번만 발생했고, 최종 output 역시 3개인 것을 알 수 있습니다.

핵심 포인트 정리

  • scope: map/reduce 함수에서 사용할 전역 변수를 정의합니다. 여기서는 카운터(oddCounter)와 나눌 값(d = 2)을 초기화했습니다.
  • emit(key, value): map 단계에서 조건에 맞는 문서를 결과로 내보냅니다. 이 예제에서는 원본 _id를 키로 사용하고, delete this._id로 value에서는 제거했습니다.
  • out: { inline: 1 }: 결과를 별도 컬렉션에 저장하지 않고 즉시 화면에 출력합니다.
  • 응용: d 값을 3으로 바꾸면 세 번째마다 하나씩 출력되도록 조건을 손쉽게 변경할 수 있습니다.

참고로 mapReduce는 MongoDB 5.0부터 집계 파이프라인(aggregation pipeline) 사용이 권장되는 기능이므로, 실무에서는 상황에 따라 $group, $match 등의 연산자를 활용한 대안도 함께 고려해 보시기 바랍니다.