我想为mapreduce代码定义一个辅助函数,可以用另一个函数(即依赖注入)进行参数化,类似于下面的定义:
var helper = function(f) {
return function(x) {
return f(x); // just an example
};
}
当调用Mongo的mapreduce时,我在范围内传递(已经解析的)函数:
var options = {
scope: {
doStuff: helper(someFun)
},
…
};
var map = function() { … };
var reduce = function(key, values) { doStuff(…); … };
db.collection('test').mapReduce(map, reduce, options);
我希望f
在返回的函数中包含someFun
,并且可以在map或reduce函数中使用。但事实并非如此,mapreduce失败了,Mongo报道:
{ MongoError: ReferenceError: f is not defined : …
可以这样做吗?我是否需要重写我的函数以保留范围/闭包?如果可能的话,我也希望避免在范围中定义f
,因为我觉得这可能会在将来中断(开发人员忘记将所有必需的功能添加到范围等)。
答案 0 :(得分:0)
我就是这样做的:
// re-useable helpers to generate mongodb map functions
// (mongoshell-compatible dependency injection)
// creates a renderDate() function to be used from map() functions
function renderDate() {
var DAY_MS = 1000 * 60 * 60 * 24;
var renderDate = t =>
new Date(DAY_MS * Math.floor(t / DAY_MS)).toISOString().split('T')[0];
}
// generates a map function after injecting code from the mapHelpers() function
function makeMapWith(mapHelpers, mapTemplate) {
const getFuncBody = fct => {
var entire = fct.toString();
return entire.substring(entire.indexOf("{") + 1, entire.lastIndexOf("}"));
};
return new Function([
getFuncBody(mapHelpers),
getFuncBody(mapTemplate),
].join('\n'));
}
const map = makeMapWith(renderDate, function mapTemplate(){
// the body of this map() function can use renderDate
// because it's injected by makeMapWith()
emit(renderDate(this._id.getTimestamp()), {});
});
// the map function can safely be passed to mongodb's mapReduce()