title: Mongodb Mapreduce join array
body: <p>I have a big collection of songs and want to get most played songs per week, in a array. as example:</p>
  
  <pre><code>{
      "_id" : {
          "title" : "demons savaites hitas",
          "name" : "imagine dragons"
      },
      "value" : {
          "weeks" : [ 
              {
                  "played" : 56,
                  "week" : 9,
                  "year" : 2014
              }
          ]
      }
  }
  </code></pre>
  
  <p>It sometimes becomes:</p>
  
  <pre><code>{
      "_id" : {
          "title" : "",
          "name" : "top 15"
      },
      "value" : {
          "played" : 1,
          "week" : 8,
          "year" : 2014
      }
  }
  </code></pre>
  
  <p>The collection which i get the data from is named songs and new fields get added all the time when a songs get added. No unique artistnames or songtitles and every document in the collection looks like this:</p>
  
  <pre><code>{
      "_id" : ObjectId("530536e3d4ca1a783342f1c8"),
      "week" : 8,
      "artistname" : "City Shakerz",
      "songtitle" : "Love Somebody (Summer 2012 Mix Edit)",
      "year" : 2014,
      "date" : ISODate("2014-02-19T22:57:39.926Z")
  }
  </code></pre>
  
  <p>I now want to do a mapreduce which add the new week to the array. It now overwrites it.
  I also noted when trying to change to a array, not all the played get counted, with the new mapreduce.</p>
  
  <p>The new mapreduce not working, with weeks:</p>
  
  <pre><code>map = function () {
  if (this.week == 9 &amp;&amp; this.year == 2014) emit({title:this.songtitle.toLowerCase(), name:this.artistname.toLowerCase()}, {played:1, week:this.week, year:this.year});
  }
  reduce = function(k, values) {
  
  var result = {};
  result.weeks = new Array();
  var object = {played:0, week: 0, year: 0};
  values.forEach(function(value) {
      object.played += value.played;
      object.week = value.week;
      object.year = value.year;
  });
  result.weeks.push(object);
  return result;
  }
  db.songs.mapReduce(map,reduce,{out: {reduce:"played2"}})
  </code></pre>
  
  <p>This is the old one i'm using with is a new field in the collection per week and song:</p>
  
  <pre><code>map = function () {
  if (this.week == 10 &amp;&amp; this.year == 2014) emit({title:this.songtitle.toLowerCase(), name:this.artistname.toLowerCase(), week:this.week, year:this.year}, {count:1});
  }
  reduce = function(k, values) {
  var result = {count: 0,};
  values.forEach(function(value) {
  result.count += value.count;
  });
  return result;
  }
  db.songs.mapReduce(map,reduce,{out: {merge:"played"}})
  </code></pre>
  
  <p>I get the information fro the toplist right now from played2 like this:</p>
  
  <pre><code>db.played2.find({'_id.week': 9,'_id.year': 2014}).sort(array("value.count" =&gt; -1)).limit(50)
  </code></pre>
  
  <p>Above line can include any typo because i use mongoclient for php and needed to change it to javascript syntax for you.</p>
  
  <p>What am I doing wrong?</p>