Javascript scoping rules and mongo map/reduce functions

closures, javascript, mongodb, mongoose, node.js

Solution

From what I read in the docs, the scope of functions to be used in database command is not their default javascript scope, but can (and must, if needed) be set manually. So, it think this should work:

var mapper = function(){
    if(item in this){
        emit(this[item], {count: 1});
    }
};
...
db.responses.mapReduce(
    mapper, 
    reducer, 
    {
       out: {"inline": 1},
       scope: {"item": item}
    }
);

Problem

I would like to make some javascript functions that perform parametric map/reduce jobs in mongo, but I'm getting confused about the scoping of JavaScript. For example, the following code gives me counts of the `"gender"` variable; i.e. it will tell me how many `"male"` and `"female"` records I have: ``` // count categories db.responses.mapReduce( function(){ emit(this["gender"], {count: 1}) }, function(state, values){ var result = {count: 0}; values.forEach(function(value) { result.count += value.count; }); return result; }, {out: { inline : 1}} ); ``` This works perfectly fine. In the next step I would like to create a function that does this for an arbitrary property ``` function countCategories(item) { function mapper(it){ fn = function(){ if(this[it]){ emit(this[it], {count: 1}); } }; return fn; }(item); var reducer = function(state, values){ var result = {count: 0}; values.forEach(function(value) { result.count += value.count; }); return result; }; var out = {out: { inline : 1}}; var results = db.responses.mapReduce( mapper, reducer, out ); return results; } countCategories("gender") ``` However when I try: ``` countCategories("gender") { "results" : [ ], "timeMillis" : 48, "counts" : { "input" : 2462, "emit" : 0, "reduce" : 0, "output" : 0 }, "ok" : 1, } ``` The emit function has never been called. What has gone wrong here? My guess is something with the scoping of the `emit` function that mongo supplies, but I'm not quite sure why it is not being called, nor throwing an error.

Original source

Related problems