先插入数据,插入的数据如下
> db.books.find() { "_id" : ObjectId("533ee1e8634249165a819cd0"), "name" : "apue", "pagenum" : 1023 } { "_id" : ObjectId("533ee273634249165a819cd1"), "name" : "clrs", "pagenum" : 2000 } { "_id" : ObjectId("533ee2ab634249165a819cd2"), "name" : "python book", "pagenum" : 600 } { "_id" : ObjectId("533ee2b7634249165a819cd3"), "name" : "golang book", "pagenum" : 400 } { "_id" : ObjectId("533ee2ca634249165a819cd4"), "name" : "linux book", "pagenum" : 1500 }
写map函数
var map = function() { var category; if ( this.pagenum >= 1000 ) category = 'Big Books'; else category = "Small Books"; emit(category, {name: this.name}); };
map说明: 里面会调用emit(key, value),集合会按照指定的key进行映射分组, 类似group by
上面map后的结果为: (按照category分组, 分组结果是{name: this.name}的list)
{"big books",[{name: "apue"}, {name : "linux book"}, {name : "clrs"}]]); {"small books",[{name: "python book"}, {name : "golang book"}]);
写reduce函数
var reduce = function(key, values) { var sum = 0; values.forEach(function(doc) { sum += 1; }); return {books: sum}; };
reduce说明:简化函数,会对map分组后的数据进行分组简化,注意:在reduce(key,value)中的key就是emit中的key,value为emit分组后的emit(value)的集合, 这里是{name: this.name}的list
写mapReduce函数
> var count = db.books.mapReduce(map, reduce, {out: "book_results"}); > db[count.result].find() { "_id" : "big books", "value" : { "books" : 3 } } { "_id" : "small books", "value" : { "books" : 2 } }
如下运行可以看详细信息
> db.books.mapReduce(map, reduce, {out: "book_results"}); { "result" : "book_results", "timeMillis" : 107, "counts" : { "input" : 5, "emit" : 5, "reduce" : 2, "output" : 2 }, "ok" : 1, } > db.book_results.find() { "_id" : "big books", "value" : { "books" : 3 } } { "_id" : "small books", "value" : { "books" : 2 } }
官网doc http://docs.mongodb.org/manual/core/map-reduce/