Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/36.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript范围规则和mongo映射/减少函数_Javascript_Node.js_Mongodb_Closures_Mongoose - Fatal编程技术网

Javascript范围规则和mongo映射/减少函数

Javascript范围规则和mongo映射/减少函数,javascript,node.js,mongodb,closures,mongoose,Javascript,Node.js,Mongodb,Closures,Mongoose,我想在mongo中创建一些javascript函数来执行参数映射/减少作业,但我对javascript的作用域感到困惑。例如,下面的代码给出了“gender”变量的计数;i、 e.它会告诉我我有多少“男性”和“女性”记录: // count categories db.responses.mapReduce( function(){ emit(this["gender"], {count: 1}) }, function(state, values){

我想在mongo中创建一些javascript函数来执行参数映射/减少作业,但我对javascript的作用域感到困惑。例如,下面的代码给出了
“gender”
变量的计数;i、 e.它会告诉我我有多少
“男性”
“女性”
记录:

// 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
函数的作用域,但我不太清楚为什么它没有被调用,也没有抛出错误。

从我所读到的内容来看,在数据库命令中使用的函数的作用域不是默认的javascript作用域,而是可以(并且必须,如果需要)手动设置的。因此,它认为这应该有效:

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

我认为你在mapper的声明中有一个问题:

您的代码:

function mapper(it){
    fn = function(){
        if(this[it]){
            emit(this[it], {count: 1});
        }
    };
    return fn;
}(item); 
由于JavaScript语法/提升/分号插入的内容,等价于:

function mapper(it){
    fn = function(){
        if(this[it]){
            emit(this[it], {count: 1});
        }
    };
    return fn;
}

item; 
您的function语句声明了一个要立即执行的函数,但您没有这样做

就其自身而言,像这样完全可以使用JavaScript。它没有任何作用,但它是有效的。(如
“使用严格”;

您需要的是函数表达式:


这里最重要的部分是在行的开头没有
功能
。函数表达式周围的
()
不是必需的,但它表示您立即执行函数。如果您没有为变量赋值,则需要它们;为了避免以
函数

开始一行,您根本不需要闭包,
已在
countCategories
的范围内定义。为什么不直接将
fn
分配给
映射器
?因为这不起作用。。。顺便说一句,我把问题改了一点。当然,这不是一个解决方案……相关:他不工作。@Bergi好吧,至少这解释了为什么你没有得到任何错误。很多内部函数fn都是在没有调用的情况下被创建和丢弃的。我认为这里的根本问题是mongo正在破坏函数的环境,以某种方式将
emit()
函数注入到它的作用域中。
var mapper = (function (it){
    fn = function(){
        if(this[it]){
            emit(this[it], {count: 1});
        }
    };
    return fn;
})(item);