我想要创建一些JavaScript函数,在mongo中执行参数化的map/reduce作业,但是我对JavaScript的范围感到困惑。例如,以下代码会给我计算“gender”变量的次数;即它将告诉我有多少条“male”和“female”的记录:
然而,当我尝试执行以下操作时:
// 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}}
);
这个可以完美地工作。接下来我想创建一个函数,使其可以针对任意属性实现此功能。
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")
然而,当我尝试执行以下操作时:
countCategories("gender")
{
"results" : [ ],
"timeMillis" : 48,
"counts" : {
"input" : 2462,
"emit" : 0,
"reduce" : 0,
"output" : 0
},
"ok" : 1,
}
emit函数从未被调用。出了什么问题? 我猜测是mongo提供的emit函数作用域有问题,但我不确定为什么它没有被调用或抛出错误。
item
已经在countCategories
的作用域中定义了。你为什么不直接将fn
分配给mapper
呢? - Bergi