Notice
Recent Posts
Recent Comments
Dharma
[MongoDB] 간단한 MapReduce 돌려보기 본문
몽고 DB 에서 간단한 맵 리듀스 (MapReduce)를 돌려보겠습니다.
예제의 원문은
http://cookbook.mongodb.org/patterns/pivot/
에서 찾을 수 있습니다.
기본이 되는 데이터를 집어 넣습니다.
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) 함수는 프레임워크가 맵 (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 에 있는 값들을 한개씩 리턴할 값에 붙여 주는 행동입니다.
실제로 mapReduce 를 구동시키고 그 결과값을 Pivot 에 써주는 작업입니다.
잘 쓰여졌는지 확인하는 작업입니다.
위 파일을 내려 받으시고 command line 상에서
라고 입력하시면 구동하시는 모습을 확인할 수 있습니다.
예제의 원문은
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'] });
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);
}
}
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;
}
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
라고 입력하시면 구동하시는 모습을 확인할 수 있습니다.