This error means that at least one object that you are reducing the map does not contain the res field of its a . Cm:
> db.NY.find({}, {_id: 0}) { "a" : { "res" : { "z" : 10011 } }, "name" : "alice" } { "a" : { "res" : { "z" : 10011 } }, "name" : "bob" } { "a" : { "res" : { "z" : 10012 } }, "name" : "carol" } > m function () { emit(this.a.res.z, 1); } > r function (key, values) { var v = 0; values.forEach(function (obj) {v += obj;}); return v; } > db.runCommand({mapreduce: "NY", map: m, reduce: r, out: {inline: 1}}) { "results" : [ { "_id" : 10011, "value" : 2 }, { "_id" : 10012, "value" : 1 } ], "timeMillis" : 0, "counts" : { "input" : 3, "emit" : 3, "output" : 2 }, "ok" : 1 } > db.NY.insert({a: {}, name: "empty"}) > db.runCommand({mapreduce: "NY", map: m, reduce: r, out: {inline: 1}}) { "assertion" : "map invoke failed: JS Error: TypeError: this.a.res has no properties nofile_b:1", "assertionCode" : 9014, "errmsg" : "db assertion failure", "ok" : 0 }
You can use the query argument to transform the map to work only with those that have the required fields:
> db.runCommand({mapreduce: "NY", map: m, reduce: r, out: {inline: 1}, query: {"a.res.z": {$exists: true}}}) { "results" : [ { "_id" : 10011, "value" : 2 }, { "_id" : 10012, "value" : 1 } ], "timeMillis" : 1, "counts" : { "input" : 3, "emit" : 3, "output" : 2 }, "ok" : 1 }
To use the query argument from PyMongo, you can set it as a keyword argument in map_reduce(...)