1

我有一个关于将 MongoDB javascript 中的参数传递给 map 函数的问题。目前,我想到的是这样的:

var map = function(n) {
    if(this.x == n){
        emit(this.x);
    }
}
var reduce = function(key, values) {
    values.forEach(function(x) {
        //do something
    });
    return {nd:values};
}
db.smsdb.mapReduce(map(2), reduce, "collection")

但是当我试图这样做时,外壳返回一个错误“不是代码”......所以我猜我没有以正确的方式这样做。有没有人对这种问题有正确的解决方案,我很高兴能把它做对。

谢谢

4

4 回答 4

1

这一行:

db.smsdb.mapReduce(map(2), reduce, "collection")

正在调用map(2),结果 ( undefined) 作为 map 函数传递mapReduce

而是做这样的事情:

db.smsdb.mapReduce(function(){ map.call(this, 2); }, reduce, "collection")

更新

以上不起作用,因为该函数在map 函数运行map的范围内不可用。mapReduce所以你必须把它包装成一个可以生成你需要的地图函数的函数:

var mapper = function(n) {
    function map() {
        if(this.x == n){
            emit(this.x);
        }
    }
    return map;
};
db.smsdb.mapReduce(mapper(2), reduce, "collection");
于 2012-12-01T17:28:31.820 回答
1

Mapreduce 中的 scope 代表 Map Reduce 中的全局参数 正如@Dave Griffith 所指出的,您可以使用mapReduce函数的范围参数。

我很难弄清楚如何正确地将它传递给函数,因为正如其他人所指出的那样,文档不是很详细。最后,我意识到需要mapReduce3 个参数:

map function
reduce function
object with one or more of the params defined in the doc
Eventually, I arrived at the following code in Javascript:

// I define a variable external to my map and to my reduce functions
var KEYS = {STATS: "stats"};

function m() {
    // I use my global variable inside the map function
    emit(KEYS.STATS, 1);
}

function r(key, values) {
    // I use a helper function
    return sumValues(values);
}

// Helper function in the global scope
function sumValues(values) {
    var result = 0;
    values.forEach(function(value) {
        result += value;
    });
    return value;
}

db.something.mapReduce(
    m,
    r,
    {
         out: {inline: 1},
         // I use the scope param to pass in my variables and functions
         scope: {
             KEYS: 1,
             sumValues: 22// of course, you can pass function objects too
         }
    }
);
于 2014-04-11T11:23:47.363 回答
0

我还应该指出,这个解决方案也有效:

var map = function() { if(this.x == n){ emit(this.x); } } db.smsdb.mapReduce(mapper, reduce, {out:"nodes",scope:{n:2}});

于 2012-12-01T20:22:56.183 回答
0

你可以这样做:

db.smsdb.mapReduce(function() { return map(2); }, reduce, "collection")
于 2012-12-01T17:19:20.150 回答