Map-Reduce Examples

In the mongo shell, the db.collection.mapReduce()method is a wrapper around the mapReduce command. Thefollowing examples use the db.collection.mapReduce() method:

Consider the following map-reduce operations on a collectionorders that contains documents of the following prototype:

  1. {
  2. _id: ObjectId("50a8240b927d5d8b5891743c"),
  3. cust_id: "abc123",
  4. ord_date: new Date("Oct 04, 2012"),
  5. status: 'A',
  6. price: 25,
  7. items: [ { sku: "mmm", qty: 5, price: 2.5 },
  8. { sku: "nnn", qty: 5, price: 2.5 } ]
  9. }

Return the Total Price Per Customer

Perform the map-reduce operation on the orders collection to groupby the cust_id, and calculate the sum of the price for eachcust_id:

  • Define the map function to process each input document:

    • In the function, this refers to the document that themap-reduce operation is processing.
    • The function maps the price to the cust_id for eachdocument and emits the cust_id and price pair.
  1. var mapFunction1 = function() {
  2. emit(this.cust_id, this.price);
  3. };
  • Define the corresponding reduce function with two argumentskeyCustId and valuesPrices:

    • The valuesPrices is an array whose elements are the pricevalues emitted by the map function and grouped by keyCustId.
    • The function reduces the valuesPrice array to thesum of its elements.
  1. var reduceFunction1 = function(keyCustId, valuesPrices) {
  2. return Array.sum(valuesPrices);
  3. };
  • Perform the map-reduce on all documents in the orders collectionusing the mapFunction1 map function and the reduceFunction1reduce function.
  1. db.orders.mapReduce(
  2. mapFunction1,
  3. reduceFunction1,
  4. { out: "map_reduce_example" }
  5. )

This operation outputs the results to a collection namedmap_reduce_example. If the map_reduce_example collectionalready exists, the operation will replace the contents with theresults of this map-reduce operation:

Calculate Order and Total Quantity with Average Quantity Per Item

In this example, you will perform a map-reduce operation on theorders collection for all documents that have an ord_datevalue greater than 01/01/2012. The operation groups by theitem.sku field, and calculates the number oforders and the total quantity ordered for each sku. The operation concludes bycalculating the average quantity per order for each sku value:

  • Define the map function to process each input document:

    • In the function, this refers to the document that themap-reduce operation is processing.
    • For each item, the function associates the sku with a newobject value that contains the count of 1 and theitem qty for the order and emits the sku and value pair.
  1. var mapFunction2 = function() {
  2. for (var idx = 0; idx < this.items.length; idx++) {
  3. var key = this.items[idx].sku;
  4. var value = {
  5. count: 1,
  6. qty: this.items[idx].qty
  7. };
  8. emit(key, value);
  9. }
  10. };
  • Define the corresponding reduce function with two argumentskeySKU and countObjVals:

    • countObjVals is an array whose elements are the objectsmapped to the grouped keySKU values passed by mapfunction to the reducer function.
    • The function reduces the countObjVals array to a singleobject reducedValue that contains the count and theqty fields.
    • In reducedVal, the count field contains the sum of thecount fields from the individual array elements, and theqty field contains the sum of the qty fields from theindividual array elements.
  1. var reduceFunction2 = function(keySKU, countObjVals) {
  2. reducedVal = { count: 0, qty: 0 };
  3.  
  4. for (var idx = 0; idx < countObjVals.length; idx++) {
  5. reducedVal.count += countObjVals[idx].count;
  6. reducedVal.qty += countObjVals[idx].qty;
  7. }
  8.  
  9. return reducedVal;
  10. };
  • Define a finalize function with two arguments key andreducedVal. The function modifies the reducedVal objectto add a computed field named avg and returns the modifiedobject:
  1. var finalizeFunction2 = function (key, reducedVal) {
  2.  
  3. reducedVal.avg = reducedVal.qty/reducedVal.count;
  4.  
  5. return reducedVal;
  6.  
  7. };
  • Perform the map-reduce operation on the orders collection usingthe mapFunction2, reduceFunction2, andfinalizeFunction2 functions.
  1. db.orders.mapReduce( mapFunction2,
  2. reduceFunction2,
  3. {
  4. out: { merge: "map_reduce_example" },
  5. query: { ord_date:
  6. { $gt: new Date('01/01/2012') }
  7. },
  8. finalize: finalizeFunction2
  9. }
  10. )

This operation uses the query field to select only thosedocuments with ord_date greater than newDate(01/01/2012). Then it output the results to a collectionmap_reduce_example. If the map_reduce_example collectionalready exists, the operation will merge the existing contents withthe results of this map-reduce operation.