몽고 DB 에서 간단한 맵 리듀스 (MapReduce)를 돌려보겠습니다.

예제의 원문은

http://cookbook.mongodb.org/patterns/pivot/

에서 찾을 수 있습니다.


db.actors.insert( { actor: "Richard Gere", movies: ['Pretty Woman', 'Runaway Bride', 'Chicago'] });
db.actors.insert( { actor: "Julia Roberts", movies: ['Pretty Woman', 'Runaway Bride', 'Erin Brockovich'] });

기본이 되는 데이터를 집어 넣습니다.

map = function() {
  for(var i in this.movies){
    key = { movie: this.movies[i] };
    value = { actors: [ this.actor ] };
    emit(key, value);
  }
}


map 함수입니다. mapreduce 를 돌리는 대상이 아래에도 나오지만 actors 이기 때문에 this 는 actors 컬렉션을 지칭한다고 보면 됩니다.

  for(var i in this.movies){

map 은 대체적으로 모든 데이터 한 row 당 매핑 (mapping) 된다고 보면 되기 때문에 actors 의 한 row 는 actor 한개와 movies 여러개가 들어 있습니다. 첫 줄은 movies 갯수만큼 for 문을 돌리라는 이야기 입니다.

    key = { movie: this.movies[i] };

key 값은 영화명으로 지정해 주는 것입니다. 해쉬 값으로 설정되는 것이겠지요? {movie: **** } 형태입니다.

    value = { actors: [ this.actor ] };

value 값은 배우명으로 지정해 주는 것입니다. 역시 해쉬 값으로 설정되는 것입니다. {actors: ***}

    emit(key, value);

map 함수들이 보통 하는 것이 reduce 에게 전달하기 위한 값들을 추출하는 것이 목적이기 때문에 (key, value) 쌍으로 값을 송출합니다.


reduce = function(key, values) {
  actor_list = { actors: [] };
  for(var i in values) {
    actor_list.actors = values[i].actors.concat(actor_list.actors);
  }
  return actor_list;
}

리듀스 (reduce) 함수는 프레임워크가 맵 (map) 함수에서 송출된 데이터를 key 값으로 정렬 시킨 값을 넘겨 받습니다. 넘겨 받는 인자가 (key, values) 로 바뀐것을 주목하시면 됩니다. 즉 map 에서 송출한 데이타들을 key 값으로 정렬한 것입니다. 즉 { movie : aaa } 라는 key 값으로 { actors : [bbb , ccc]} 라는 값으로 넘어옵니다.

  actor_list = { actors: [] };

reduce 함수는 일정한 형태로 값을 넘겨 받아야 합니다. 그 형식을 만들어 주는 것이라고 보면 됩니다. (단  key, value 가 한개씩 붙어 있는 형태는 reduce 를 거치지 않고 바로 db 에 쓰여집니다)

  for(var i in values) {
    actor_list.actors = values[i].actors.concat(actor_list.actors);
  }

values 에 있는 값들을 한개씩 리턴할 값에 붙여 주는 행동입니다.


printjson(db.actors.mapReduce(map, reduce, "pivot"));


실제로 mapReduce 를 구동시키고 그 결과값을 Pivot 에 써주는 작업입니다.

db.pivot.find().forEach(printjson);


잘 쓰여졌는지 확인하는 작업입니다.

위 파일을 내려 받으시고 command line 상에서

$ mongo movie-star.js --shell


라고 입력하시면 구동하시는 모습을 확인할 수 있습니다.


+ Recent posts