맵리듀스(Map-Reduce)란 무엇인가?
맵리듀스(Map-Reduce)는 대량의 데이터를 처리하여 유용한 집계 결과로 압축·정제하기 위한 데이터 처리 패러다임입니다. MongoDB에서는 mapReduce() 메서드를 사용해 컬렉션에 저장된 문서들을 그룹화하고, 통계 계산이나 집합 연산 등 다양한 집계 작업을 수행할 수 있습니다.
맵리듀스는 크게 두 단계로 동작합니다.
- Map(맵) 단계: 각 문서를 순회하며 emit() 함수를 통해 키-값 쌍을 생성합니다.
- Reduce(리듀스) 단계: 동일한 키를 가진 값들을 모아 하나의 요약된 결과로 병합합니다.
예제 컬렉션 생성하기
먼저 실습을 위한 컬렉션과 문서를 생성해 보겠습니다.
> db.demo280.insertOne({"CustomerName":"Chris","isMarried":true});
{
"acknowledged" : true,
"insertedId" : ObjectId("5e49116edd099650a5401a62")
}
> db.demo280.insertOne({"CustomerName":"Mike","isMarried":false});
{
"acknowledged" : true,
"insertedId" : ObjectId("5e491170dd099650a5401a63")
}
> db.demo280.insertOne({"CustomerName":"David","isMarried":false});
{
"acknowledged" : true,
"insertedId" : ObjectId("5e491170dd099650a5401a64")
}
> db.demo280.insertOne({"CustomerName":"Bob","isMarried":true});
{
"acknowledged" : true,
"insertedId" : ObjectId("5e491171dd099650a5401a65")
}저장된 문서 확인하기
find() 메서드를 사용하면 컬렉션 내 모든 문서를 조회할 수 있습니다.
> db.demo280.find();
위 명령을 실행하면 다음과 같은 출력 결과를 확인할 수 있습니다.
{ "_id" : ObjectId("5e49116edd099650a5401a62"), "CustomerName" : "Chris", "isMarried" : true }
{ "_id" : ObjectId("5e491170dd099650a5401a63"), "CustomerName" : "Mike", "isMarried" : false }
{ "_id" : ObjectId("5e491170dd099650a5401a64"), "CustomerName" : "David", "isMarried" : false }
{ "_id" : ObjectId("5e491171dd099650a5401a65"), "CustomerName" : "Bob", "isMarried" : true }총 4개의 고객 문서가 저장되어 있으며, 이 중 결혼 여부(isMarried)가 true인 고객은 Chris와 Bob 두 명입니다.
맵리듀스 쿼리 구현하기
이제 MongoDB에서 맵리듀스를 실제로 구현하는 쿼리를 살펴보겠습니다. 아래 예제는 isMarried가 true인 문서만 필터링하여 해당 고객 수를 집계하는 코드입니다.
> db.demo280.mapReduce(
... function() { emit(this.isMarried,true); },
...
... function(key, values) {return Array.sum(values)}, {
... query:{isMarried:true},
... out:"Output"
... }
...)쿼리의 주요 구성 요소는 다음과 같습니다.
- map 함수: 각 문서에서 isMarried 값을 키로 하여 true라는 값을 emit() 합니다.
- reduce 함수: 같은 키로 묶인 값들의 합계를 Array.sum()으로 계산합니다.
- query 옵션: isMarried가 true인 문서만 맵 단계에 전달되도록 필터링합니다.
- out 옵션: 집계 결과를 'Output'이라는 이름의 새 컬렉션에 저장합니다.
실행 결과 분석
맵리듀스 작업이 완료되면 다음과 같은 실행 통계가 출력됩니다.
{
"result" : "Output",
"timeMillis" : 1241,
"counts" : {
"input" : 2,
"emit" : 2,
"reduce" : 1,
"output" : 1
},
"ok" : 1
}출력 결과를 해석해 보면 다음과 같습니다.
- input: 2 — query 조건에 일치하여 맵 단계에 입력된 문서 수 (Chris와 Bob)
- emit: 2 — map 함수가 호출되어 키-값 쌍을 생성한 횟수
- reduce: 1 — reduce 함수가 호출된 횟수
- output: 1 — 최종적으로 'Output' 컬렉션에 저장된 결과 문서 수
즉, 총 2개의 문서가 쿼리 조건에 매칭되었고(map 입력: 2), 2개의 결과가 emit 되었으며, 최종적으로 하나의 집계 결과가 산출되었습니다. 이처럼 MongoDB의 맵리듀스는 복잡한 집계 로직을 JavaScript 함수 기반으로 유연하게 구현할 수 있는 강력한 도구입니다.