title: Translate aggregation operation in MongoDB to MapReduce
body: <p>I've been trying to translate this query into MapReduce for a few days. Specifically, I need to figure out how many different cars have driven "N" kilometers.</p>
  
  <p>Query:</p>
  
  <pre><code>db.adsb.group({
      "key": {
          "KM": true
      },
      "initial": {
          "countCar": 0
      },
      "reduce": function(obj, prev) {
          if (obj.Matricula != null) if (obj.Matricula instanceof Array) prev.countCar += obj.Matricula.length;
          else prev.countCar++;
      },
      "cond": {
          "KM": {
              "$gt": 10000,
              "$lt": 45000
          }
      }
  });
  </code></pre>
  
  <p>Each document in Mongo has this form:</p>
  
  <pre><code>{
          "_id" : ObjectId("5a8843e7d79a740f272ccc0a"),
          "KM" : 45782,
          "Matricula" : "3687KTS",
  }
  </code></pre>
  
  <p>I'm trying to get something like:</p>
  
  <pre><code> /* 0 */
   {
       “KM” : 45000,
       “total” : 634
   }
  
   /* 1 */
   {
       “KM” : 46000,
       “total” : 784
   }
  </code></pre>
  
  <p>My code is below, and it compiles but does not give me the expected results. </p>
  
  <p>In particular, every time I enter 'reduce' it seems to reset all the values to 0, which prevents me from accumulating the registrations.
  One of my problems is that when handling large amounts of information, the function must iterate several times ' reduce'.
  I also don't know if it could be done that way, or I would need to return a list of car plates and their counter together in 'reduce'; and then in finalize add it all up. </p>
  
  <pre><code>// Map function
  var m = function() {
    if (this.KM &gt; 10000 &amp;&amp; this.KM &lt; 45000) { // So that i can get KM grouped together by thousands (10000, 20000, 30000...)
      var fl = Math.round(this.KM / 1000) * 1000;
      var car = this.Matricula
      emit (fl, car);
      //print("map KM=" + fl + " Matricula= " + car);
    }
  };
  
  // Reduce function
  var r = function(key, values) {
      var ya_incluido = false;
      var cars_totales = 0;
      var lista_car = new Array();
  
      //print( key + " ---- " + values);
  
      for (var i=0; i &lt; values.length;i++)
      {
              for (var j=0; j &lt; lista_car.length;j++)
              {
                      if(values[i] == lista_car[j]) { //If it is already included, don't aggregate it
                              ya_incluido = true;
                      }
  
              } if (ya_incluido != true) { //If it is not included, add it to lista_av list.
                      lista_car.push(values[i]);
              } ya_incluido = false;
      }
  
      cars_totales = lista_av.length; //The number of distinct cars is equal to the lenght of the list we created
      return cars_totales;
  
  };
  
  
  // Finalize function
  var f = function(key,value) {
    // Sum up the results?
  
  }
  
  
  db.runCommand( {
                   mapReduce: "dealer",
                   map: m,
                   reduce: r,
                   finalize: f,
                   out: {replace : "result"}
                 } );
  </code></pre>
  
  <p><strong>I found the answer and a really good explanation here:</strong> <a href="https://stackoverflow.com/a/27532153/13474284">https://stackoverflow.com/a/27532153/13474284</a></p>