Uploaded image for project: 'Core Server'
  1. Core Server
  2. SERVER-68766

Add option to re-enable single value MapReduce optimization

    • Fully Compatible
    • ALL
    • v6.1, v6.0, v5.0, v4.4
    • Hide

      Running against mongod version 4.4:

      var collName = "mrtest"
      var coll = db[collName];
      coll.drop()
      coll.insert({a:1})
      
      const runMR = () => coll.mapReduce(
          function(){emit(0, "mapped value")}, 
          function(key,value){return "reduced value"}, 
          {out: {inline: 1} }
      ).results;
      
      db.adminCommand({setFeatureCompatibilityVersion: "4.2"})
      printjson(runMR())
      // >>> [ { "_id" : 0, "value" : "mapped value" } ]
      
      db.adminCommand({setFeatureCompatibilityVersion: "4.4"})
      printjson(runMR())
      // >>> [ { "_id" : 0, "value" : "reduced value" } ]
      
      Show
      Running against mongod version 4.4: var collName = "mrtest" var coll = db[collName]; coll.drop() coll.insert({a:1}) const runMR = () => coll.mapReduce( function(){emit(0, "mapped value" )}, function(key,value){ return "reduced value" }, {out: {inline: 1} } ).results; db.adminCommand({setFeatureCompatibilityVersion: "4.2" }) printjson(runMR()) // >>> [ { "_id" : 0, "value" : "mapped value" } ] db.adminCommand({setFeatureCompatibilityVersion: "4.4" }) printjson(runMR()) // >>> [ { "_id" : 0, "value" : "reduced value" } ]
    • QO 2022-08-22, QO 2022-09-05

      This is in the documentation for MapReduce from 4.2 to 6.0:

      MongoDB will not call the reduce function for a key that has only a single value. The values argument is an array whose elements are the value objects that are "mapped" to the key.

      However, from 4.4 onwards, the reduce function will be called regardless of how many values are associated with a given key. PM-766 added a new execution engine for MapReduce commands based on the Aggregation Framework that is active in 4.4 and above.
       
      If the implementation is changed, then two possible fixes are:

      1. AccumulatorJsReduce::getValue() can be modified to not call into the JS reduce function if the length the _values vector is exactly 1. Instead, it will just return that value to the caller. This fix has the benefit of not adding any logic to the generated MQL.
      2. The translateReduce() function can be modified to only call the internal JsReduce accumulator if the $emits array has a length larger than 1, and otherwise, just return the document inside $emits.
         

            Assignee:
            davis.haupt@mongodb.com Davis Haupt (Inactive)
            Reporter:
            davis.haupt@mongodb.com Davis Haupt (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            7 Start watching this issue

              Created:
              Updated:
              Resolved: