{"id":44348,"date":"2015-09-23T22:43:41","date_gmt":"2015-09-23T19:43:41","guid":{"rendered":"http:\/\/www.javacodegeeks.com\/?p=44348"},"modified":"2023-12-06T15:09:06","modified_gmt":"2023-12-06T13:09:06","slug":"mongodb-mapreduce-tutorial","status":"publish","type":"post","link":"https:\/\/www.javacodegeeks.com\/2015\/09\/mongodb-mapreduce-tutorial.html","title":{"rendered":"MongoDB MapReduce Tutorial"},"content":{"rendered":"<p><em>This article is part of our Academy Course titled <a href=\"http:\/\/www.javacodegeeks.com\/2015\/09\/mongodb-a-scalable-nosql-db\/\">MongoDB \u2013 A Scalable NoSQL DB<\/a>.<\/em><\/p>\n<p><em>In this course, you will get introduced to MongoDB. You will learn how to install it and how to operate it via its shell. Moreover, you will learn how to programmatically access it via Java and how to leverage Map Reduce with it. Finally, more advanced concepts like sharding and replication will be explained. Check it out <a href=\"http:\/\/www.javacodegeeks.com\/2015\/09\/mongodb-a-scalable-nosql-db\/\">here<\/a>!<\/em><\/p>\n<div class=\"toc\">\n<h4>Table Of Contents<\/h4>\n<dl>\n<dt><a href=\"#introduction\">1. Introduction<\/a><\/dt>\n<dt><a href=\"#mapataglance\">2. Map\/Reduce At a Glance<\/a><\/dt>\n<dt><a href=\"#mapreduce\">3. Map\/Reduce in MongoDB<\/a><\/dt>\n<dd>\n<dl>\n<dt><a href=\"#dataset\">3.1. Dataset<\/a><\/dt>\n<dt><a href=\"#example1\">3.2. Example: Count books by author<\/a><\/dt>\n<dt><a href=\"#example2\">3.3. Example: Count average book price by publisher<\/a><\/dt>\n<dt><a href=\"#example3\">3.4. Example: Incrementally count average book price by publisher<\/a><\/dt>\n<\/dl>\n<\/dd>\n<dt><a href=\"#whatsnext\">4. What&#8217;s next<\/a><\/dt>\n<\/dl>\n<\/div>\n<h2><a name=\"introduction\"><\/a>1. Introduction<\/h2>\n<p>The <a href=\"http:\/\/en.wikipedia.org\/wiki\/MapReduce\">Map\/Reduce<\/a> paradigm, firstly popularized by Google (for the curious readers, here is a <a href=\"http:\/\/research.google.com\/archive\/mapreduce.html\">link to original paper<\/a>), has gotten a lot of traction these days, mostly because of the Big Data movement. Many NoSQL solutions aim to support integration with <a href=\"http:\/\/en.wikipedia.org\/wiki\/MapReduce\">Map\/Reduce<\/a> frameworks but <a href=\"http:\/\/www.mongodb.org\/\">MongoDB<\/a> goes further than that and provides its <a href=\"http:\/\/docs.mongodb.org\/manual\/core\/map-reduce\/\">own Map\/Reduce<\/a> implementation integrated into the MongoDB server, available for everyone to consume.<\/p>\n<h2><a name=\"mapataglance\"><\/a>2. Map\/Reduce At a Glance<\/h2>\n<p><a href=\"http:\/\/en.wikipedia.org\/wiki\/MapReduce\">Map\/Reduce<\/a> is a framework which allows to parallelize the processing of large and very large datasets across many physical or virtual servers. A typical <a href=\"http:\/\/en.wikipedia.org\/wiki\/MapReduce\">Map\/Reduce<\/a> program consists of two phases:<\/p>\n<ul>\n<li><strong>map<\/strong> phase: filter \/ transform \/ convert data<\/li>\n<li><strong>reduce<\/strong> phase: perform aggregations over the data<\/li>\n<\/ul>\n<p>In some extent, the <strong>map<\/strong> and <strong>reduce<\/strong> phases were inspired by <a href=\"http:\/\/en.wikipedia.org\/wiki\/Map_(higher-order_function)\">map<\/a> and <a href=\"http:\/\/en.wikipedia.org\/wiki\/Fold_(higher-order_function)\">reduce<\/a>, the high-order functions widely used and well known in the <a href=\"http:\/\/en.wikipedia.org\/wiki\/Functional_programming\">functional programming<\/a> world. As the name <a href=\"http:\/\/en.wikipedia.org\/wiki\/MapReduce\">Map\/Reduce<\/a> implies, the <strong>map<\/strong> job is always performed before the <strong>reduce<\/strong> job. Please note that the modern approaches to data processing are more sophisticated than the one described before, but the principles remain the same.<\/p>\n<p>From an implementation prospective, most <a href=\"http:\/\/en.wikipedia.org\/wiki\/MapReduce\">Map\/Reduce<\/a> frameworks operate on <strong>tuples<\/strong>. The <strong>map<\/strong> implementation accepts some set of data and transforms it into another set of data, typically <strong>tuples<\/strong> (key\/value pairs). Consequently, the <strong>reduce<\/strong> implementation accepts the output from a <strong>map<\/strong> implementation as its input and combines (reduces) those <strong>tuples<\/strong> into a smaller (aggregated) set of <strong>tuples<\/strong>, which eventually becomes a final result.<\/p>\n<p>Let us look back on <strong>bookstore<\/strong> example we have seen in <a href=\"http:\/\/www.javacodegeeks.com\/2015\/09\/mongodb-and-java-tutorial\/\"><strong>Part 3. MongoDB and Java Tutorial<\/strong><\/a> and try to apply the <a href=\"http:\/\/en.wikipedia.org\/wiki\/MapReduce\">Map\/Reduce<\/a> paradigm to it in order to get aggregated results on how many books each author has published. The <strong>map<\/strong> function just iterates over the <strong>authors<\/strong> property of each document and for each author <strong>emits<\/strong> (very common term referring to generation of the new output) the key\/value tuple <strong>(author, 1)<\/strong>.<\/p>\n<pre class=\"brush:java\">\nfunction map(document):\n  for each author in document.authors:\n    emit( author, 1 )\n<\/pre>\n<p>The <strong>reduce<\/strong> function accepts the key and collection of values (taken from tuples), aggregates them and <strong>emits <\/strong>(again, new output) new tuples where each author has the total number of books he has published.<\/p>\n<pre class=\"brush:java\">\nfunction reduce(author, values):\n  sum = 0\n  for each value in values:\n    sum += value\n  emit( author, sum )\n<\/pre>\n<p><figure id=\"attachment_5263\" aria-describedby=\"caption-attachment-5263\" style=\"width: 674px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2015\/09\/06_MAP__REDUCE.png\"><img decoding=\"async\" class=\"size-full wp-image-5263\" src=\"http:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2015\/09\/06_MAP__REDUCE.png\" alt=\"Picture 1. Map\/Reduce example by phases.\" width=\"674\" height=\"222\" \/><\/a><figcaption id=\"caption-attachment-5263\" class=\"wp-caption-text\"><strong>Picture 1<\/strong>. <a href=\"http:\/\/en.wikipedia.org\/wiki\/MapReduce\">Map\/Reduce<\/a> example by phases.<\/figcaption><\/figure><\/p>\n<p>It looks quite simple and may not seem to bring a lot of value. But simplicity here is a key which allows to split the large problem into smaller parts and to distribute computation across hundreds or thousands of servers (nodes): massively parallel data processing.<\/p>\n<h2><a name=\"mapreduce\"><\/a>3. Map\/Reduce in MongoDB<\/h2>\n<p><a href=\"http:\/\/www.mongodb.org\/\">MongoDB<\/a> provides the single command <strong>mapReduce<\/strong> (and respective <strong>MongoDB<\/strong> shell wrapper <code>db.&lt;collection&gt;.mapReduce()<\/code>) to run <a href=\"http:\/\/en.wikipedia.org\/wiki\/MapReduce\">Map\/Reduce<\/a> aggregations across collection of documents. The command accpets a plenty of different parameters and in this section we are going to walk through all of them.<\/p>\n<div class=\"wp-caption aligncenter\">\n<table>\n<tbody>\n<tr>\n<td width=\"85\"><strong>Command<\/strong><\/td>\n<td width=\"576\"><strong>mapReduce<\/strong><\/td>\n<\/tr>\n<tr>\n<td width=\"85\"><strong>Parameters<\/strong><\/td>\n<td width=\"576\">\n<pre class=\"brush:bash\">{\n    mapReduce: &lt;collection&gt;,\n    map: &lt;function&gt;,\n    reduce: &lt;function&gt;,\n    out: &lt;output&gt;,\n    query: &lt;document&gt;,\n    sort: &lt;document&gt;,\n    limit: &lt;number&gt;,\n    finalize: &lt;function&gt;,\n    scope: &lt;document&gt;,\n    jsMode: &lt;true|false&gt;,\n    verbose: &lt;true|false&gt;\n}\n<\/pre>\n<\/td>\n<\/tr>\n<tr>\n<td width=\"85\"><strong>Wrapper<\/strong><\/td>\n<td width=\"576\">\n<pre class=\"brush:bash\">db.&lt;collection&gt;.mapReduce(\n    map,\n    reduce, {\n        out: &lt;collection&gt;,\n        query: &lt;document&gt;,\n        sort: &lt;document&gt;,\n        limit: &lt;number&gt;,\n        finalize: &lt;function&gt;,\n        scope: &lt;document&gt;,\n        jsMode: &lt;true|false&gt;,\n        verbose: &lt;true|false&gt;\n} )\n<\/pre>\n<\/td>\n<\/tr>\n<tr>\n<td width=\"85\"><strong>Description<\/strong><\/td>\n<td width=\"576\">The command allows to run map\/reduce aggregation operation over the documents of collection <strong>&lt;collection&gt;<\/strong>.<\/td>\n<\/tr>\n<tr>\n<td width=\"85\"><strong>Reference<\/strong><\/td>\n<td width=\"576\"><a href=\"http:\/\/docs.mongodb.org\/manual\/reference\/command\/mapReduce\/\">http:\/\/docs.mongodb.org\/manual\/reference\/command\/mapReduce\/<\/a><a href=\"http:\/\/docs.mongodb.org\/manual\/reference\/method\/db.collection.mapReduce\/\">http:\/\/docs.mongodb.org\/manual\/reference\/method\/db.collection.mapReduce\/<\/a><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p class=\"wp-caption-text\">Table 1<\/p>\n<\/div>\n<p>The<strong> mapReduce<\/strong> command operates on single input collection (which may be <strong>sharded<\/strong>) and may produce the single output collection, which also may be <strong>sharded<\/strong>. Before feeding the data into the <strong>map<\/strong> function, the command allows to perform any arbitrary sorting and limiting of input collection.<\/p>\n<div class=\"wp-caption aligncenter\">\n<table>\n<tbody>\n<tr>\n<td width=\"85\"><strong>sort<\/strong><\/td>\n<td width=\"576\">An optional document which may specify the order of the input documents. Specifying the sort key to be the same as the emit key may result in fewer reduce operation invocations. The sort key must be in an existing index for the collection in question.<\/td>\n<\/tr>\n<tr>\n<td width=\"85\"><strong>limit<\/strong><\/td>\n<td width=\"576\">An optional parameter which specifies a maximum number of documents to be returned from the collection (or as the result of the query).<\/td>\n<\/tr>\n<tr>\n<td width=\"85\"><strong>query<\/strong><\/td>\n<td width=\"576\">An optional document which specifies the matching criteria (using full set of query operators described in <strong><a href=\"http:\/\/www.javacodegeeks.com\/2015\/09\/mongodb-shell-guide-operations-and-commands\/\">Part 2. MongoDB Shell Guide &#8211; Operations and Commands<\/a><\/strong>) for documents which should be sent as an input to the <strong>map<\/strong> function.<\/td>\n<\/tr>\n<tr>\n<td width=\"85\"><strong>verbose<\/strong><\/td>\n<td width=\"576\">An optional parameter which allows to include the timing information of the command execution in the result. By default, the <strong>verbose<\/strong> has value set to <strong>true<\/strong> and the timing information is included into result (as we will see in the examples below).<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p class=\"wp-caption-text\">Table 2<\/p>\n<\/div>\n<p>The <strong>map<\/strong> and <strong>reduce<\/strong> functions in <a href=\"http:\/\/www.mongodb.org\/\">MongoDB<\/a> are JavaScript functions and run within the <a href=\"http:\/\/www.mongodb.org\/\">MongoDB<\/a> server process. The <strong>map<\/strong> function takes the documents of a single collection as the input and applies custom JavaScript functions to emit new output.<div style=\"display:inline-block; margin: 15px 0;\"> <div id=\"adngin-JavaCodeGeeks_incontent_video-0\" style=\"display:inline-block;\"><\/div> <\/div><\/p>\n<div class=\"wp-caption aligncenter\">\n<table>\n<tbody>\n<tr>\n<td width=\"85\"><strong>scope<\/strong><\/td>\n<td width=\"576\">An optional document which specifies the global variables that could be accessible in the <strong>map<\/strong>, <strong>reduce<\/strong> and <strong>finalize<\/strong> functions.<\/td>\n<\/tr>\n<tr>\n<td width=\"85\"><strong>map<\/strong><\/td>\n<td width=\"576\">A JavaScript function that accepts the document as input and emits new key \/ value tuple(s). It has the following prototype definition:<\/p>\n<pre class=\"brush:java\">function() {\n   \/\/ do something, this references the current document\n   emit(key, value);\n}\n<\/pre>\n<p>This function has the following context and constraints:<\/p>\n<ul>\n<li>within the function, <strong>this<\/strong> references the current document<\/li>\n<li>within the function, the implementation should not try to access any database<\/li>\n<li>the implementation should be side-effect free (pure function)<\/li>\n<li>the implementation may refer to the variables defined in the <strong>scope<\/strong> parameter<\/li>\n<\/ul>\n<p>Implementation may call the <strong>emit<\/strong> function 0 or more times, depending on the kind of output the <strong>map<\/strong> function is expected to produce.<\/td>\n<\/tr>\n<tr>\n<td width=\"85\"><strong>reduce<\/strong><\/td>\n<td width=\"576\">A JavaScript function that accepts key and values and returns the aggregated result for this particular key (each value inside values conforms to the output of <strong>map<\/strong> function). It has the following prototype definition:<\/p>\n<pre class=\"brush:java\">function(key, values) {\n    \/\/ do some aggregations here\n    return result;\n}\n<\/pre>\n<p>This function has the following context and constraints:<\/p>\n<ul>\n<li>within the function, the implementation should not try to access any database<\/li>\n<li>the implementation should be side-effect free (pure function)<\/li>\n<li>the implementation may refer to the variables defined in the <strong>scope<\/strong> parameter<\/li>\n<li>the function will not be called for a key that has only a single value<\/li>\n<\/ul>\n<p>There is also one very important aspect of <strong>reduce<\/strong> function to keep in mind: it might be called more than once for the same key. In this case, the result from the previous invocation for that key becomes one of the input values to the next invocation for the same key. Because of such behavior, the <strong>reduce<\/strong> function implementation should be designed in such a way that following constraints are satisfied:<\/p>\n<ul>\n<li>the type of the <strong>result <\/strong>value must be identical to the type of the value emitted by the <strong>map<\/strong> function<\/li>\n<li>the order of the elements in the <strong>values<\/strong> argument should not affect the result of the function<\/li>\n<li>and last but not least, the function should be <a href=\"http:\/\/en.wikipedia.org\/wiki\/Idempotence\">idempotent<\/a> (it can be applied multiple times without changing the result beyond the initial application): <code>reduce( key, reduce( key, values ) ) == reduce( key, values )<\/code><\/li>\n<\/ul>\n<\/td>\n<\/tr>\n<tr>\n<td width=\"85\"><strong>finalize<\/strong><\/td>\n<td width=\"576\">An optional JavaScript function that accepts key and reduced value (the result of the <strong>reduce<\/strong> function calls) and returns the final result of the aggregation. It has the following prototype definition:<\/p>\n<pre class=\"brush:java\">function(key, value) {\n    \/\/ do some final aggregations here\n    return result;\n}\n<\/pre>\n<p>And, similarly to <strong>map<\/strong> and <strong>reduce<\/strong>, this function has the following context and constraints:<\/p>\n<ul>\n<li>withinthefunction, the implementation should not try to access any database<\/li>\n<li>the implementation should be side-effect free (pure function)<\/li>\n<li>the implementation may refer to the variables defined in the <strong>scope<\/strong> parameter<\/li>\n<\/ul>\n<\/td>\n<\/tr>\n<tr>\n<td width=\"85\"><strong>jsMode<\/strong><\/td>\n<td width=\"576\">An optional parameter which specifies if the intermediate data should be converted into <a href=\"http:\/\/bsonspec.org\/\">BSON format<\/a> between the execution of the <strong>map<\/strong> and <strong>reduce<\/strong> functions. When provided, it has the following implications:<\/p>\n<ul>\n<li>if set to <strong>false<\/strong> (default):<\/li>\n<\/ul>\n<p>The JavaScript objects emitted by the <strong>map<\/strong> function will be converted to <a href=\"http:\/\/bsonspec.org\/\">BSON<\/a> objects. These <a href=\"http:\/\/bsonspec.org\/\">BSON<\/a> objects will be converted back to JavaScript objects when the <strong>reduce<\/strong> function is called. The <a href=\"http:\/\/docs.mongodb.org\/manual\/core\/map-reduce\/\">map\/reduce<\/a> operation places the intermediate <a href=\"http:\/\/bsonspec.org\/\">BSON<\/a> objects in temporary storage on the disk which allows the execution over arbitrarily large data sets (which may not fit into memory).<\/p>\n<ul>\n<li>if set to<strong> true<\/strong>:<\/li>\n<\/ul>\n<p>The JavaScript objects emitted by the <strong>map<\/strong> function will remain the JavaScript objects which can lead to much faster executions. However, the result set is limited to 500,000 distinct key arguments passed through the <code>emit(key, value)<\/code> function invocation.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p class=\"wp-caption-text\">Table 3<\/p>\n<\/div>\n<p>When a <strong>mapReduce<\/strong> command is run in a way that it is using <strong>sharded<\/strong> collection (please refer to <a href=\"http:\/\/www.javacodegeeks.com\/2015\/09\/mongodb-sharding-guide\/\"><strong>Part 4. MongoDB Sharding Guide <\/strong><\/a>for more details) as the input, <strong>mongos <\/strong>process will automatically dispatch the map\/reduce command to each <strong>shard<\/strong> in parallel and will wait for jobs on all shards to finish. Consequently, if the <strong>mapReduce<\/strong> command is run in a way that it is using <strong>sharded<\/strong> collections as an output, <a href=\"http:\/\/www.mongodb.org\/\">MongoDB<\/a> shards the output collection using the <strong>_id<\/strong> field as the <strong>shard key<\/strong>.<\/p>\n<div class=\"wp-caption aligncenter\">\n<table>\n<tbody>\n<tr>\n<td width=\"85\"><strong>out<\/strong><\/td>\n<td width=\"576\">A simple string or a document which outlines the location of the result of the <a href=\"http:\/\/docs.mongodb.org\/manual\/core\/map-reduce\/\">map\/reduce<\/a> operation. There are three possible output scenarios:<\/p>\n<ul>\n<li>output to a collection (when executed on <strong>primary<\/strong> members of <strong>replica sets<\/strong> only or standalone instance)<\/li>\n<\/ul>\n<pre class=\"brush:bash\">out: &lt;collection&gt;<\/pre>\n<ul>\n<li>output to a collection with an action (when executed on <strong>primary<\/strong> members of <strong>replica sets<\/strong> only or standalone instance)<\/li>\n<\/ul>\n<pre class=\"brush:java\">out: {\n    &lt;action&gt;: &lt;collection&gt;,\n    db: &lt;db&gt;,\n    sharded: &lt;true|false&gt;,\n    nonAtomic: &lt;true|false&gt;\n}\n<\/pre>\n<p>The <strong>collection<\/strong> parameter specifies the output collection name, while the action parameter may have one of the following values (which prescribes how to resolve the conflicts in the case when <strong>collection <\/strong>already exists):<\/p>\n<ul>\n<li><strong>replace<\/strong>:replaces the contents of the<strong> collection<\/strong><\/li>\n<li><strong>merge<\/strong>: merges the new results with the existing <strong>collection <\/strong>(if the document with same key already exists, it will be overridden)<\/li>\n<li><strong>reduce<\/strong>: merges the new results with the existing <strong>collection <\/strong>(if the document with same key already exists, the <strong>reduce<\/strong> function will be applied to both new and existing documents and the existing document will be overridden with the result of the function call)<\/li>\n<\/ul>\n<p>The <strong>db<\/strong> parameter is optional and specifies the name of the database where the resulting <strong>collection<\/strong> should be located. By default, the name of the database will be the same as for the input collection.<\/p>\n<p>The optional <strong>sharded<\/strong> parameter enables (or disables) <strong>sharding<\/strong> for the output <strong>collection<\/strong>. If it is set to <strong>true<\/strong>, the output <strong>collection<\/strong> will be sharded using the <strong>_id<\/strong> property as the <strong>shard key<\/strong>.<\/p>\n<p>The optional <strong>nonAtomic<\/strong> parameter hints the <strong>MongoDB<\/strong> server if the database where the output <strong>collection <\/strong>resides should be locked or not. If it is set to <strong>true<\/strong>, the database will not be locked and other clients may read intermediate states of the output <strong>collection<\/strong>. Consequently, if it is set to <strong>false<\/strong>, the database will be locked and unlocked only when the processing finishes. The <strong>nonAtomic<\/strong> parameter is valid only for <strong>merge<\/strong> and <strong>reduce<\/strong> actions and comes into play in post-processing step.<\/p>\n<ul>\n<li>inline output: the <a href=\"http:\/\/docs.mongodb.org\/manual\/core\/map-reduce\/\">map\/reduce<\/a> operation is performed in memory and returns the complete result (the only option available for the <strong>secondary<\/strong> members of <strong>replica sets<\/strong>).<\/li>\n<\/ul>\n<pre class=\"brush:bash\">out: { inline: 1 }<\/pre>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p class=\"wp-caption-text\">Table 4<\/p>\n<\/div>\n<h3><a name=\"dataset\"><\/a>3.1. Dataset<\/h3>\n<p>We are going to adapt the bookstore example from <a href=\"http:\/\/www.javacodegeeks.com\/2015\/09\/mongodb-sharding-guide\/\"><strong>Part 4. MongoDB Sharding Guide<\/strong><\/a> to illustrate different map\/reduce scenarios using the books collection.<\/p>\n<pre class=\"brush:java\">\ndb.books.insert( {\n    \"title\" : \"MongoDB: The Definitive Guide\",\n    \"published\" : \"2013-05-23\",\n    \"authors\": [\n        { \"firstName\" : \"Kristina\",  \"lastName\" : \"Chodorow\" }\n    ],\n    \"categories\" : [ \"Databases\", \"NoSQL\", \"Programming\" ],\n    \"publisher\" : { \"name\" : \"O'Reilly\" },\n    \"price\" : 32.99\n} )\n<\/pre>\n<pre class=\"brush:java\">\ndb.books.insert( {\n    \"title\" : \"MongoDB Applied Design Patterns\",\n    \"published\" : \"2013-03-19\",\n    \"authors\": [\n        { \"firstName\" : \"Rick\",  \"lastName\" : \"Copeland\" }\n    ],\n    \"categories\" : [ \"Databases\", \"NoSQL\", \"Patterns\", \"Programming\" ],\n    \"publisher\" : { \"name\" : \"O'Reilly\" },\n    \"price\" : 32.99\n} )\n<\/pre>\n<pre class=\"brush:java\">\ndb.books.insert( {\n    \"title\" : \"MongoDB in Action\",\n    \"published\" : \"2011-12-16\",\n    \"authors\": [\n        { \"firstName\" : \"Kyle\",  \"lastName\" : \"Banker\" }\n    ],\n    \"categories\" : [ \"Databases\", \"NoSQL\", \"Programming\" ],\n    \"publisher\" : { \"name\" : \"Manning\" },\n    \"price\" : 30.83\n} )\n<\/pre>\n<pre class=\"brush:java\">\ndb.books.insert( {\n    \"title\" : \"NoSQL Distilled: A Brief Guide to the Emerging World of Polyglot Persistence\",\n    \"published\" : \"2012-08-18\",\n    \"authors\": [\n        { \"firstName\" : \"Pramod J.\",  \"lastName\" : \"Sadalage\" },\n        { \"firstName\" : \"Martin\",  \"lastName\" : \"Fowler\" }\n    ],\n    \"categories\" : [ \"Databases\", \"NoSQL\" ],\n    \"publisher\" : { \"name\" : \"Addison Wesley\" },\n    \"price\" : 26.36\n} )\n<\/pre>\n<pre class=\"brush:java\">\ndb.books.insert( {\n    \"title\" : \"Scaling MongoDB\",\n    \"published\" : \"2011-03-07\",\n    \"authors\": [\n        { \"firstName\" : \"Kristina\",  \"lastName\" : \"Chodorow\" }\n    ],\n    \"categories\" : [ \"Databases\", \"NoSQL\" ],\n    \"publisher\" : { \"name\" : \"O'Reilly\" },\n    \"price\" : 25.30\n} )\n<\/pre>\n<pre class=\"brush:java\">\ndb.books.insert( {\n    \"title\" : \"50 Tips and Tricks for MongoDB Developers\",\n    \"published\" : \"2011-05-06\",\n    \"authors\": [\n        { \"firstName\" : \"Kristina\",  \"lastName\" : \"Chodorow\" }\n    ],\n    \"categories\" : [ \"Databases\", \"NoSQL\", \"Programming\" ],\n    \"publisher\" : { \"name\" : \"O'Reilly\" },\n    \"price\" : 25.08\n} )\n<\/pre>\n<pre class=\"brush:java\">\ndb.books.insert( {\n    \"title\" : \"MongoDB in Action, 2nd Edition\",\n    \"published\" : \"2014-12-01\",\n    \"authors\": [\n        { \"firstName\" : \"Kyle\",  \"lastName\" : \"Banker\" },\n        { \"firstName\" : \"Peter\",  \"lastName\" : \"Bakkum\" },\n        { \"firstName\" : \"Tim\",  \"lastName\" : \"Hawkins\" }\n    ],\n    \"categories\" : [ \"Databases\", \"NoSQL\", \"Programming\" ],\n    \"publisher\" : { \"name\" : \"Manning\" },\n    \"price\" : 26.66\n} )\n<\/pre>\n<pre class=\"brush:java\">\ndb.books.insert( {\n    \"title\" : \"Node.js, MongoDB, and AngularJS Web Development\",\n    \"published\" : \"2014-04-04\",\n    \"authors\": [\n        { \"firstName\" : \"Brad\",  \"lastName\" : \"Dayley\" }\n    ],\n    \"categories\" : [ \"Databases\", \"NoSQL\", \"Programming\", \"Web\" ],\n    \"publisher\" : { \"name\" : \"Addison Wesley\" },\n    \"price\" : 34.35\n} )\n<\/pre>\n<p>Once the <strong>books<\/strong> collection is filled with those documents (the best way to do that is using <a href=\"http:\/\/www.mongodb.org\/\">MongoDB<\/a> shell), we are ready to start playing with <a href=\"http:\/\/docs.mongodb.org\/manual\/core\/map-reduce\/\">map\/reduce<\/a> by examples.<\/p>\n<h3><a name=\"example1\"><\/a>3.2. Example: Count books by author<\/h3>\n<p>Let us start with the simplest scenario and run <strong>MongoDB<\/strong> <a href=\"http:\/\/docs.mongodb.org\/manual\/core\/map-reduce\/\">map\/reduce<\/a> command to complete the example we have looked at in <a href=\"#_Map\/Reduce_At_a\">Map\/Reduce At a Glance<\/a> section: count books by author.<\/p>\n<pre class=\"brush:java\">\ndb.runCommand( {\n    mapReduce: \"books\",\n    map: function() {\n        for (var index = 0; index &lt; this.authors.length; ++index) {\n            var author = this.authors[ index ];\n            emit( author.firstName + \" \" + author.lastName, 1 );\n        }\n    },\n    reduce: function(author, counters) {\n        count = 0;\n\n        for (var index = 0; index &lt; counters.length; ++index) {\n            count += counters[index];\n        }\n\n        return count;\n    },\n    out: { inline: 1 }\n} )\n<\/pre>\n<p>If we run this command in <a href=\"http:\/\/www.mongodb.org\/\">MongoDB<\/a> shell, the following document will be returned as the result of <a href=\"http:\/\/docs.mongodb.org\/manual\/core\/map-reduce\/\">map\/reduce<\/a> command:<\/p>\n<pre class=\"brush:java\">\n{\n    \"results\" : [\n        {\n            \"_id\" : \"Brad Dayley\",\n            \"value\" : 1\n        },\n        {\n            \"_id\" : \"Kristina Chodorow\",\n            \"value\" : 3\n        },\n        {\n            \"_id\" : \"Kyle Banker\",\n            \"value\" : 2\n        },\n        {\n            \"_id\" : \"Martin Fowler\",\n            \"value\" : 1\n        },\n        {\n            \"_id\" : \"Peter Bakkum\",\n            \"value\" : 1\n        },\n        {\n            \"_id\" : \"Pramod J. Sadalage\",\n            \"value\" : 1\n        },\n        {\n            \"_id\" : \"Rick Copeland\",\n            \"value\" : 1\n        },\n        {\n            \"_id\" : \"Tim Hawkins\",\n            \"value\" : 1\n        }\n    ],\n    \"timeMillis\" : 1,\n    \"counts\" : {\n        \"input\" : 8,\n        \"emit\" : 11,\n        \"reduce\" : 2,\n        \"output\" : 8\n    },\n    \"ok\" : 1\n}\n<\/pre>\n<p>Quite clear output and as we can see each author is accompanied by the total number of his books from the input collection.<\/p>\n<h3><a name=\"example2\"><\/a>3.3. Example: Count average book price by publisher<\/h3>\n<p>The next example we are going to look at is a bit more complicated and introduces three new elements for the <a href=\"http:\/\/docs.mongodb.org\/manual\/core\/map-reduce\/\">map\/reduce<\/a> command: <strong>finalize<\/strong>, <strong>scope<\/strong> and <strong>output to collection <\/strong>with name <strong>results<\/strong>. We are going to count average book price per publisher using a particular currency (f.e. US dollar).<\/p>\n<pre class=\"brush:java\">\ndb.runCommand( {\n    mapReduce: \"books\",\n    scope: { currency: \"US\" },\n    map: function() {\n        emit( this.publisher, { count: 1, price: this.price } );\n    },\n    reduce: function(publisher, values) {\n        var value = { count: 0, price: 0 };\n\n        for (var index = 0; index &lt; values.length; ++index) {\n            value.count += values[index].count;\n            value.price += values[index].price;\n        }\n\n        return value;\n    },\n    finalize: function(publisher, value) {\n        value.average = currency + ( value.price \/ value.count ).toFixed(2);\n        return value;\n    },\n    out: {\n        replace: \"results\"\n    }\n} )\n<\/pre>\n<p>In this example, the <strong>scope<\/strong> document introduces a global variable <strong>currency<\/strong> to the context of the <a href=\"http:\/\/docs.mongodb.org\/manual\/core\/map-reduce\/\">map\/reduce<\/a> operation (<strong>map<\/strong>, <strong>reduce<\/strong> and <strong>finalize<\/strong> functions). As you might already have figured out, the average price could be computed only when all the documents have been processed and that is why the <strong>finalize<\/strong> function is being introduced: it is called once all <strong>map<\/strong> and <strong>reduce<\/strong> steps are over. The final output of the <a href=\"http:\/\/docs.mongodb.org\/manual\/core\/map-reduce\/\">map\/reduce<\/a> operation will be stored in the <strong>results<\/strong> collection (<strong>bookstore<\/strong> database). If we run this command in <a href=\"http:\/\/www.mongodb.org\/\">MongoDB<\/a> shell, the following document will be returned as the result:<\/p>\n<pre class=\"brush:java\">\n{\n    \"result\" : \"results\",\n    \"timeMillis\" : 50,\n    \"counts\" : {\n        \"input\" : 8,\n        \"emit\" : 8,\n        \"reduce\" : 3,\n        \"output\" : 3\n    },\n    \"ok\" : 1\n}\n<\/pre>\n<p>And the <strong>results<\/strong> collection holds following documents (which could be retrieved by running command wrapper <code>db.results.find().pretty()<\/code> in the <a href=\"http:\/\/www.mongodb.org\/\">MongoDB<\/a> shell):<\/p>\n<pre class=\"brush:java\">\n{\n    \"_id\" : {\n        \"name\" : \"Addison Wesley\"\n    },\n    \"value\" : {\n        \"count\" : 2,\n        \"price\" : 60.71,\n        \"average\" : \"US30.36\"\n    }\n}\n{\n    \"_id\" : {\n        \"name\" : \"Manning\"\n    },\n    \"value\" : {\n        \"count\" : 2,\n        \"price\" : 57.489999999999995,\n        \"average\" : \"US28.74\"\n    }\n}\n{\n    \"_id\" : {\n        \"name\" : \"O'Reilly\"\n    },\n    \"value\" : {\n        \"count\" : 4,\n        \"price\" : 116.36,\n        \"average\" : \"US29.09\"\n    }\n}\n<\/pre>\n<h3><a name=\"example3\"><\/a>3.4. Example: Incrementally count average book price by publisher<\/h3>\n<p>This last example is going to demonstrate the incremental nature of the <a href=\"http:\/\/docs.mongodb.org\/manual\/core\/map-reduce\/\">map\/reduce<\/a> implementation in <a href=\"http:\/\/www.mongodb.org\/\">MongoDB<\/a>. Let us assume that since we have counted average book price by publisher, there are two new books added into collection.<\/p>\n<pre class=\"brush:java\">\ndb.books.insert( {\n    \"title\" : \"MongoDB and Python: Patterns and processes for the popular document-oriented database\",\n    \"published\" : \"2011-09-30\",\n    \"authors\": [\n        { \"firstName\" : \" Niall\",  \"lastName\" : \"O'Higgins\" }\n    ],\n    \"categories\" : [ \"Databases\", \"NoSQL\", \"Programming\" ],\n    \"publisher\" : { \"name\" : \"O'Reilly\" },\n    \"price\" : 18.06\n} )\n<\/pre>\n<pre class=\"brush:java\">\ndb.books.insert( {\n    \"title\" : \" Node.js in Action\",\n    \"published\" : \"2013-11-28\",\n    \"authors\": [\n        { \"firstName\" : \" Mike\",  \"lastName\" : \"Cantelon\" }\n    ],\n    \"categories\" : [ \"Databases\", \"NoSQL\", \"Programming\", \"Web\" ],\n    \"publisher\" : { \"name\" : \"Manning\" },\n    \"price\" : 26.09\n} )\n<\/pre>\n<p>Now, we have a couple of choices here in order to get the updated average book price by publisher: we may rerun the <a href=\"http:\/\/docs.mongodb.org\/manual\/core\/map-reduce\/\">map\/reduce<\/a> command again across all the documents in the collection or perform an incremental update of the existing results with new documents only. The latter will be the objective of this example. The <strong>map<\/strong>, <strong>reduce<\/strong> and <strong>finalize<\/strong> functions are the same as for a previous example. The two new parameters we are going to add are <strong>limit<\/strong> and <strong>query<\/strong> to filter out those two new books only, plus the output collection is going to be merged using the <strong>reduce<\/strong> operation (<strong>out<\/strong> parameter).<\/p>\n<pre class=\"brush:java\">\ndb.runCommand( {\n    mapReduce: \"books\",\n    scope: { currency: \"US\" },\n    map: function() {\n        emit( this.publisher, { count: 1, price: this.price } );\n    },\n    reduce: function(publisher, values) {\n        var value = { count: 0, price: 0 };\n\n        for (var index = 0; index &lt; values.length; ++index) {\n            value.count += values[index].count;\n            value.price += values[index].price;\n        }\n\n        return value;\n    },\n    finalize: function(publisher, value) {\n        value.average = currency + ( value.price \/ value.count ).toFixed(2);\n        return value;\n    },\n    query: { \"authors.lastName\": { $in: [ \"Cantelon\", \"O'Higgins\" ] } },\n    limit: 2,\n    out: {\n        reduce: \"results\"\n    }\n} )\n<\/pre>\n<p>The <strong>query<\/strong> filter includes only the books published by two new authors. For the demonstration purposes, the <strong>limit<\/strong> is also set to 2 but it is not very useful as we know for sure that only two new books have been added. If we run this command in <a href=\"http:\/\/www.mongodb.org\/\">MongoDB<\/a> shell, the following document will be returned as the result:<\/p>\n<pre class=\"brush:java\">\n{\n    \"result\" : \"results\",\n    \"timeMillis\" : 4,\n    \"counts\" : {\n        \"input\" : 2,\n        \"emit\" : 2,\n        \"reduce\" : 0,\n        \"output\" : 3\n    },\n    \"ok\" : 1\n}\n<\/pre>\n<p>Please notice that the <strong>reduce<\/strong> function has not been called at all because each key (publisher) contains just a single value (please refer to <a href=\"#_Map\/Reduce_in_MongoDB\">Map\/Reduce in MongoDB<\/a> section for these subtle details).<\/p>\n<p>And here are the documents in the <strong>results<\/strong> collection (please compare them with the documents from <a href=\"#_Example:_Count_average\">Example: Count average book price by publisher<\/a> section):<\/p>\n<pre class=\"brush:java\">\n{\n    \"_id\" : {\n        \"name\" : \"Addison Wesley\"\n    },\n    \"value\" : {\n        \"count\" : 2,\n        \"price\" : 60.71,\n        \"average\" : \"US30.36\"\n    }\n}\n{\n    \"_id\" : {\n        \"name\" : \"Manning\"\n    },\n    \"value\" : {\n        \"count\" : 3,\n        \"price\" : 83.58,\n        \"average\" : \"US27.86\"\n    }\n}\n{\n    \"_id\" : {\n        \"name\" : \"O'Reilly\"\n    },\n    \"value\" : {\n        \"count\" : 5,\n        \"price\" : 134.42,\n        \"average\" : \"US26.88\"\n    }\n}\n<\/pre>\n<p>As we can see, the existing <strong>results <\/strong>collection has been updated incrementally using a proper merging algorithm.<\/p>\n<h2><a name=\"whatsnext\"><\/a>4. What&#8217;s next<\/h2>\n<p>This part of the tutorial concludes the basic but still detailed enough overview of <a href=\"http:\/\/www.mongodb.org\/\">MongoDB<\/a> document database features. In the <a href=\"http:\/\/www.javacodegeeks.com\/2015\/09\/mongodb-security-profiling-indexing-cursors-and-bulk-operations-guide\/\">last part of the course<\/a> we are going to look deeper under the cover and hopefully reveal some interesting details about <a href=\"http:\/\/www.mongodb.org\/\">MongoDB<\/a> internals and advanced concepts.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This article is part of our Academy Course titled MongoDB \u2013 A Scalable NoSQL DB. In this course, you will get introduced to MongoDB. You will learn how to install it and how to operate it via its shell. Moreover, you will learn how to programmatically access it via Java and how to leverage Map &hellip;<\/p>\n","protected":false},"author":141,"featured_media":187,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[15],"tags":[112],"class_list":["post-44348","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-software-development","tag-mongodb"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.5 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>MongoDB MapReduce Tutorial - Java Code Geeks<\/title>\n<meta name=\"description\" content=\"This article is part of our Academy Course titled MongoDB \u2013 A Scalable NoSQL DB. In this course, you will get introduced to MongoDB. You will learn how to\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.javacodegeeks.com\/2015\/09\/mongodb-mapreduce-tutorial.html\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"MongoDB MapReduce Tutorial - Java Code Geeks\" \/>\n<meta property=\"og:description\" content=\"This article is part of our Academy Course titled MongoDB \u2013 A Scalable NoSQL DB. In this course, you will get introduced to MongoDB. You will learn how to\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.javacodegeeks.com\/2015\/09\/mongodb-mapreduce-tutorial.html\" \/>\n<meta property=\"og:site_name\" content=\"Java Code Geeks\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/javacodegeeks\" \/>\n<meta property=\"article:published_time\" content=\"2015-09-23T19:43:41+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2023-12-06T13:09:06+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/mongodb-logo.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"150\" \/>\n\t<meta property=\"og:image:height\" content=\"150\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Andrey Redko\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@javacodegeeks\" \/>\n<meta name=\"twitter:site\" content=\"@javacodegeeks\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Andrey Redko\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"11 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2015\\\/09\\\/mongodb-mapreduce-tutorial.html#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2015\\\/09\\\/mongodb-mapreduce-tutorial.html\"},\"author\":{\"name\":\"Andrey Redko\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/person\\\/771a6504862edc45322776832cbce413\"},\"headline\":\"MongoDB MapReduce Tutorial\",\"datePublished\":\"2015-09-23T19:43:41+00:00\",\"dateModified\":\"2023-12-06T13:09:06+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2015\\\/09\\\/mongodb-mapreduce-tutorial.html\"},\"wordCount\":2464,\"commentCount\":3,\"publisher\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2015\\\/09\\\/mongodb-mapreduce-tutorial.html#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/mongodb-logo.jpg\",\"keywords\":[\"MongoDB\"],\"articleSection\":[\"Software Development\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.javacodegeeks.com\\\/2015\\\/09\\\/mongodb-mapreduce-tutorial.html#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2015\\\/09\\\/mongodb-mapreduce-tutorial.html\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2015\\\/09\\\/mongodb-mapreduce-tutorial.html\",\"name\":\"MongoDB MapReduce Tutorial - Java Code Geeks\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2015\\\/09\\\/mongodb-mapreduce-tutorial.html#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2015\\\/09\\\/mongodb-mapreduce-tutorial.html#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/mongodb-logo.jpg\",\"datePublished\":\"2015-09-23T19:43:41+00:00\",\"dateModified\":\"2023-12-06T13:09:06+00:00\",\"description\":\"This article is part of our Academy Course titled MongoDB \u2013 A Scalable NoSQL DB. In this course, you will get introduced to MongoDB. You will learn how to\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2015\\\/09\\\/mongodb-mapreduce-tutorial.html#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.javacodegeeks.com\\\/2015\\\/09\\\/mongodb-mapreduce-tutorial.html\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2015\\\/09\\\/mongodb-mapreduce-tutorial.html#primaryimage\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/mongodb-logo.jpg\",\"contentUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/mongodb-logo.jpg\",\"width\":150,\"height\":150},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2015\\\/09\\\/mongodb-mapreduce-tutorial.html#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Software Development\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/category\\\/software-development\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"MongoDB MapReduce Tutorial\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#website\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\",\"name\":\"Java Code Geeks\",\"description\":\"Java Developers Resource Center\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\"},\"alternateName\":\"JCG\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.javacodegeeks.com\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\",\"name\":\"Exelixis Media P.C.\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2022\\\/06\\\/exelixis-logo.png\",\"contentUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2022\\\/06\\\/exelixis-logo.png\",\"width\":864,\"height\":246,\"caption\":\"Exelixis Media P.C.\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/logo\\\/image\\\/\"},\"sameAs\":[\"https:\\\/\\\/www.facebook.com\\\/javacodegeeks\",\"https:\\\/\\\/x.com\\\/javacodegeeks\"]},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/person\\\/771a6504862edc45322776832cbce413\",\"name\":\"Andrey Redko\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/16419ce8394173028eddaeb992859862bab50cfcf74589fa9bb9a3dd8bb27518?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/16419ce8394173028eddaeb992859862bab50cfcf74589fa9bb9a3dd8bb27518?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/16419ce8394173028eddaeb992859862bab50cfcf74589fa9bb9a3dd8bb27518?s=96&d=mm&r=g\",\"caption\":\"Andrey Redko\"},\"description\":\"Andriy is a well-grounded software developer with more then 12 years of practical experience using Java\\\/EE, C#\\\/.NET, C++, Groovy, Ruby, functional programming (Scala), databases (MySQL, PostgreSQL, Oracle) and NoSQL solutions (MongoDB, Redis).\",\"sameAs\":[\"http:\\\/\\\/aredko.blogspot.com\\\/\",\"http:\\\/\\\/ca.linkedin.com\\\/in\\\/aredko\"],\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/author\\\/andrey-redko\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"MongoDB MapReduce Tutorial - Java Code Geeks","description":"This article is part of our Academy Course titled MongoDB \u2013 A Scalable NoSQL DB. In this course, you will get introduced to MongoDB. You will learn how to","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.javacodegeeks.com\/2015\/09\/mongodb-mapreduce-tutorial.html","og_locale":"en_US","og_type":"article","og_title":"MongoDB MapReduce Tutorial - Java Code Geeks","og_description":"This article is part of our Academy Course titled MongoDB \u2013 A Scalable NoSQL DB. In this course, you will get introduced to MongoDB. You will learn how to","og_url":"https:\/\/www.javacodegeeks.com\/2015\/09\/mongodb-mapreduce-tutorial.html","og_site_name":"Java Code Geeks","article_publisher":"https:\/\/www.facebook.com\/javacodegeeks","article_published_time":"2015-09-23T19:43:41+00:00","article_modified_time":"2023-12-06T13:09:06+00:00","og_image":[{"width":150,"height":150,"url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/mongodb-logo.jpg","type":"image\/jpeg"}],"author":"Andrey Redko","twitter_card":"summary_large_image","twitter_creator":"@javacodegeeks","twitter_site":"@javacodegeeks","twitter_misc":{"Written by":"Andrey Redko","Est. reading time":"11 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.javacodegeeks.com\/2015\/09\/mongodb-mapreduce-tutorial.html#article","isPartOf":{"@id":"https:\/\/www.javacodegeeks.com\/2015\/09\/mongodb-mapreduce-tutorial.html"},"author":{"name":"Andrey Redko","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/person\/771a6504862edc45322776832cbce413"},"headline":"MongoDB MapReduce Tutorial","datePublished":"2015-09-23T19:43:41+00:00","dateModified":"2023-12-06T13:09:06+00:00","mainEntityOfPage":{"@id":"https:\/\/www.javacodegeeks.com\/2015\/09\/mongodb-mapreduce-tutorial.html"},"wordCount":2464,"commentCount":3,"publisher":{"@id":"https:\/\/www.javacodegeeks.com\/#organization"},"image":{"@id":"https:\/\/www.javacodegeeks.com\/2015\/09\/mongodb-mapreduce-tutorial.html#primaryimage"},"thumbnailUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/mongodb-logo.jpg","keywords":["MongoDB"],"articleSection":["Software Development"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.javacodegeeks.com\/2015\/09\/mongodb-mapreduce-tutorial.html#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.javacodegeeks.com\/2015\/09\/mongodb-mapreduce-tutorial.html","url":"https:\/\/www.javacodegeeks.com\/2015\/09\/mongodb-mapreduce-tutorial.html","name":"MongoDB MapReduce Tutorial - Java Code Geeks","isPartOf":{"@id":"https:\/\/www.javacodegeeks.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.javacodegeeks.com\/2015\/09\/mongodb-mapreduce-tutorial.html#primaryimage"},"image":{"@id":"https:\/\/www.javacodegeeks.com\/2015\/09\/mongodb-mapreduce-tutorial.html#primaryimage"},"thumbnailUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/mongodb-logo.jpg","datePublished":"2015-09-23T19:43:41+00:00","dateModified":"2023-12-06T13:09:06+00:00","description":"This article is part of our Academy Course titled MongoDB \u2013 A Scalable NoSQL DB. In this course, you will get introduced to MongoDB. You will learn how to","breadcrumb":{"@id":"https:\/\/www.javacodegeeks.com\/2015\/09\/mongodb-mapreduce-tutorial.html#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.javacodegeeks.com\/2015\/09\/mongodb-mapreduce-tutorial.html"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.javacodegeeks.com\/2015\/09\/mongodb-mapreduce-tutorial.html#primaryimage","url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/mongodb-logo.jpg","contentUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/mongodb-logo.jpg","width":150,"height":150},{"@type":"BreadcrumbList","@id":"https:\/\/www.javacodegeeks.com\/2015\/09\/mongodb-mapreduce-tutorial.html#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.javacodegeeks.com\/"},{"@type":"ListItem","position":2,"name":"Software Development","item":"https:\/\/www.javacodegeeks.com\/category\/software-development"},{"@type":"ListItem","position":3,"name":"MongoDB MapReduce Tutorial"}]},{"@type":"WebSite","@id":"https:\/\/www.javacodegeeks.com\/#website","url":"https:\/\/www.javacodegeeks.com\/","name":"Java Code Geeks","description":"Java Developers Resource Center","publisher":{"@id":"https:\/\/www.javacodegeeks.com\/#organization"},"alternateName":"JCG","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.javacodegeeks.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.javacodegeeks.com\/#organization","name":"Exelixis Media P.C.","url":"https:\/\/www.javacodegeeks.com\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/logo\/image\/","url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","contentUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","width":864,"height":246,"caption":"Exelixis Media P.C."},"image":{"@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/javacodegeeks","https:\/\/x.com\/javacodegeeks"]},{"@type":"Person","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/person\/771a6504862edc45322776832cbce413","name":"Andrey Redko","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/16419ce8394173028eddaeb992859862bab50cfcf74589fa9bb9a3dd8bb27518?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/16419ce8394173028eddaeb992859862bab50cfcf74589fa9bb9a3dd8bb27518?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/16419ce8394173028eddaeb992859862bab50cfcf74589fa9bb9a3dd8bb27518?s=96&d=mm&r=g","caption":"Andrey Redko"},"description":"Andriy is a well-grounded software developer with more then 12 years of practical experience using Java\/EE, C#\/.NET, C++, Groovy, Ruby, functional programming (Scala), databases (MySQL, PostgreSQL, Oracle) and NoSQL solutions (MongoDB, Redis).","sameAs":["http:\/\/aredko.blogspot.com\/","http:\/\/ca.linkedin.com\/in\/aredko"],"url":"https:\/\/www.javacodegeeks.com\/author\/andrey-redko"}]}},"_links":{"self":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts\/44348","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/users\/141"}],"replies":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/comments?post=44348"}],"version-history":[{"count":0,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts\/44348\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/media\/187"}],"wp:attachment":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/media?parent=44348"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/categories?post=44348"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/tags?post=44348"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}