title: Merging two collections in MongoDB
body: <p>I've been trying to use MapReduce in MongoDB to do what I think is a simple procedure. I don't know if this is the right approach, of if I should even be using MapReduce. I googled what keywords I thought of and tried to hit the docs where I thought I would have the most success - but nothing. Maybe I'm thinking too hard about this?</p>
  
  <p>I have two collections: <code>details</code> and <code>gpas</code></p>
  
  <p><code>details</code> is made up of a whole bunch of documents (3+ million). The <code>studentid</code> element can be repeated two times, one for each <code>year</code>, like the following:</p>
  
  <pre><code>{ "_id" : ObjectId("4d49b7yah5b6d8372v640100"), "classes" : [1,17,19,21], "studentid" : "12345a", "year" : 1}
  { "_id" : ObjectId("4d76b7oij7s2d8372v640100"), "classes" : [2,12,19,22], "studentid" : "98765a", "year" : 1}
  { "_id" : ObjectId("4d49b7oij7s2d8372v640100"), "classes" : [32,91,101,217], "studentid" : "12345a", "year" : 2}
  { "_id" : ObjectId("4d76b7rty7s2d8372v640100"), "classes" : [1,11,18,22], "studentid" : "24680a", "year" : 1}
  { "_id" : ObjectId("4d49b7oij7s2d8856v640100"), "classes" : [32,99,110,215], "studentid" : "98765a", "year" : 2}
  ...
  </code></pre>
  
  <p><code>gpas</code> has elements with the same <code>studentid</code>'s from <code>details</code>. Only one entry per <code>studentid</code>, like this:</p>
  
  <pre><code>{ "_id" : ObjectId("4d49b7yah5b6d8372v640111"), "studentid" : "12345a", "overall" : 97, "subscore": 1}
  { "_id" : ObjectId("4f76b7oij7s2d8372v640213"), "studentid" : "98765a", "overall" : 85, "subscore": 5}
  { "_id" : ObjectId("4j49b7oij7s2d8372v640871"), "studentid" : "24680a", "overall" : 76, "subscore": 2}
  ...
  </code></pre>
  
  <p>In the end I want to have a collection with one row for each student in this format:</p>
  
  <pre><code>{ "_id" : ObjectId("4d49b7yah5b6d8372v640111"), "studentid" : "12345a", "classes_1": [1,17,19,21], "classes_2": [32,91,101,217], "overall" : 97, "subscore": 1}
  { "_id" : ObjectId("4f76b7oij7s2d8372v640213"), "studentid" : "98765a", "classes_1": [2,12,19,22], "classes_2": [32,99,110,215], "overall" : 85, "subscore": 5}
  { "_id" : ObjectId("4j49b7oij7s2d8372v640871"), "studentid" : "24680a", "classes_1": [1,11,18,22], "classes_2": [], "overall" : 76, "subscore": 2}
  ...
  </code></pre>
  
  <p>The way I was going to do this was by running MapReduce like this:</p>
  
  <pre><code>var mapDetails = function() {
      emit(this.studentid, {studentid: this.studentid, classes: this.classes, year: this.year, overall: 0, subscore: 0});
  };
  
  var mapGpas = function() {
      emit(this.studentid, {studentid: this.studentid, classes: [], year: 0, overall: this.overall, subscore: this.subscore});
  };
  
  var reduce = function(key, values) {
      var outs = { studentid: "0", classes_1: [], classes_2: [], overall: 0, subscore: 0};
  
      values.forEach(function(value) {
          if (value.year == 0) {
              outs.overall = value.overall;
              outs.subscore = value.subscore;
          }
          else {
              if (value.year == 1) {
                  outs.classes_1 = value.classes;
              }
              if (value.year == 2) {
                  outs.classes_2 = value.classes;
              }
  
              outs.studentid = value.studentid;
          }
      });
  
      return outs;
  
  };
  
  res = db.details.mapReduce(mapDetails, reduce, {out: {reduce: 'joined'}})
  res = db.gpas.mapReduce(mapGpas, reduce, {out: {reduce: 'joined'}})
  </code></pre>
  
  <p>But when I run it, this is my resulting collection:</p>
  
  <pre><code>{ "_id" : "12345a", "value" : { "studentid" : "12345a", "classes_1" : [ ], "classes_2" : [ ], "overall" : 97, "subscore" : 1 } }
  { "_id" : "98765a", "value" : { "studentid" : "98765a", "classes_1" : [ ], "classes_2" : [ ], "overall" : 85, "subscore" : 5 } }
  { "_id" : "24680a", "value" : { "studentid" : "24680a", "classes_1" : [ ], "classes_2" : [ ], "overall" : 76, "subscore" : 2 } }
  </code></pre>
  
  <p>I'm missing the classes arrays.</p>
  
  <p>Also, as an aside, how do I access the elements in resulting MapReduce <code>value</code> element? Does MapReduce always output to <code>value</code> or whatever else you name it?</p>