3

I have a collection where each document looks like this

{access_key:'xxxxxxxxx', keyword: "banana", count:12, request_hour:"Thu Sep 30 2010 12:00:00 GMT+0000 (UTC)"}
{access_key:'yyyyyyyyy', keyword: "apple", count:25, request_hour:"Thu Sep 30 2010 12:00:00 GMT+0000 (UTC)", }
.....

To achieve this:

SELECT keyword, sum(count) FROM keywords_counter WHERE access_key = 'xxxxxxxxx' GROUP BY keyword

I'm doing this:

db.keywords_counter.group({key     : {keyword:true}, 
                          cond    : {access_key: "xxxxx"}, 
                          reduce  : function(obj, prev){prev.total += obj.count},
                          initial : {total:0}})

How do I achieve the same thing with map/reduce? [I'm a map/reduce beginner and trying to wrap my head around the concept.]

rubayeet
  • 9,269
  • 8
  • 46
  • 55

1 Answers1

4

Found the solution:

map = function(){ emit(this.keyword, {count: this.count}); }

reduce = function(key, values){
             var total = 0;
             for (var i=0; i < values.length, i++) { total += values[i].count; }
             return {count: total};
         }

db.keywords_counter.mapReduce(map, reduce, {query:{access_key: 'xxxxxxxxx'}})
rubayeet
  • 9,269
  • 8
  • 46
  • 55
  • thanks, it helped a lot. But im still working on it, because im getting a count of 0. – theTuxRacer Oct 05 '10 at 09:28
  • @thetuxracer - check if the 2nd parameter to emit is identical to the object returned by reduce. It worked for me. – rubayeet Oct 05 '10 at 11:49
  • i got it, i was incorrectly adding the count, i ddnt use the value array. but your comment helped me clarify another query :D – theTuxRacer Oct 05 '10 at 13:28