2017-10-01 15 views
2
私は下記の定義と同様、他の機能(すなわち依存性注入)でパラメータ化することができ、私のMapReduceコードのためのヘルパー関数を定義したい

のMongoDBのMapReduceスコープ

var helper = function(f) { 
    return function(x) { 
    return f(x); // just an example 
    }; 
} 

はモンゴの呼び出し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が含まれていますし、マップで使用することができるかの機能を削減することを期待します。しかし、それは、MapReduceは失敗していないとモンゴレポート:

{ MongoError: ReferenceError: f is not defined : …

はこれが行われることはできますか?スコープ/クロージャが保持されるように関数を書き直す必要がありますか?可能であれば、 fをスコープに定義しないようにしたいと思っています。これは将来的に壊れる可能性があるためです(開発者はスコープに必要な機能をすべて忘れてしまうなど)

+0

Javascriptの 'this'キーワードはそうではありませんか? – Deano

+0

正しい方法で 'this'を使って私の問題を解決できてうれしく思いますが、私の質問とは無関係だと思います。 – knittl

答えて

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() 
関連する問題