Database Reference
In-Depth Information
If you now want to see the document results, you need to query them from the mrresult collection, as follows:
> db.mrresult.findOne();
{ "_id" : "black", "value" : 45318 }
Now that we have a basic system working we can get more advanced!
Advanced MapReduce
Let's say that instead of the sum of all values we want the average! This becomes far harder, as we need to add another
variable—the number of objects we have! But how can we pass two variables out from the map function? After all, the
emit takes only two arguments. We can perform a “cheat” of sorts; we return a JSON document, which can have as many
fields as we want! So let's expand our original map function to return a document that contains the color value and a
counter value. First we define the document as a new variable, fill in the JSON document, and then emit that document.
var map = function() {
var value = {
num : this.num,
count : 1
};
emit(this.color, value);
};
Notice that we set the counter value to 1, in order to count each document only once! Now for the reduce
function. It will need to deal with an array of those value documents that we created earlier. One last thing to note is
that we need to return the same values in our reduce function's return function that are created in our map function
and sent to our emit.
You could also accomplish all of the things we are doing here by using the length of the array containing all the
numbers. But this way you get to see more of what you can do with Mapreduce.
Note
To deal with this array, we've created a simple for loop, the length of the array, and we iterate over each member
and add the num and count for each document onto our new return variable, called reduceValue . Now we simply
return this value and we have our result.
var reduce = function(color, val ) {
reduceValue = { num : 0, count : 0};
for (var i = 0; i < val.length; i++) {
reduceValue.num += val[i].num;
reduceValue.count += val[i].count;
}
return reduceValue;
};
At this point, you should be wondering how this gets us our average. We have the count and the number, but no
actual average! If you run the MapReduce again you can see the results for yourself. Now, be warned that each
time you output to a collection, MapReduce will drop that collection before writing to it! For us that's a good thing, as
we only want this run's results but it could come back to haunt you in the future. If you want to merge the results of the
two you can make an output document that looks like { out : { merge : "mrresult" } } .
 
 
Search WWH ::




Custom Search