我在“system.js”集合中存储了两个名为“mapfun”和“reducefun”的函数,我试图从java调用这些函数。我试图通过 MapReduceCommand 调用这些函数。我无法调用这些函数。谁能帮我解决这个问题吗? 这两个函数看起来像这样 //mapfun
{ "_id" : "mapfun","value" : { "code" : "function(){var criteria; if(this.speed > 70 ){ criteria="overspeed";emit(criteria,this.speed); } }" } }
//reducefun
{ "_id" : "reducefun", "value" : { "code" : "function(key,speed){ var total=0; for(var i=0;i<speed.length;i++){ total=total+speed[i]; } return total/speed.length; }" } }
我的mapreduce命令看起来像这样
MapReduceCommand command=new MapReduceCommand(collection, map, reduce, null, MapReduceCommand.OutputType.INLINE, null);
MapReduceOutput output=collection.mapReduce(command);
我已经将map和reduce函数作为字符串传递,其中我分别调用了mapfun和reducefun 它看起来像这样
String map = "function (){var x=mapfun();"
+ "return x;};";
String reduce = "function(key, speed) {var y=reducefun(key,speed);"
+ "return y;};";
我在这里做错了什么以及如何纠正这个问题请帮助我。
最佳答案
根本问题是为每个函数调用重新分配 this
变量。
为了演示,我从 mongo shell 运行了一个简短的测试。
首先创建一个包含 1 个文档的集合:
MongoDB Enterprise replset:PRIMARY> db.maptest.find({},{_id:0})
{ "canary" : "tweet" }
然后创建一个存储函数,该函数将接受一个参数并发出 2 个值,一个使用 this
,另一个使用传递的参数:
MongoDB Enterprise replset:PRIMARY> db.system.js.find()
{ "_id" : "testfun", "value" : { "code" : "function(arg){emit(\"this.canary\",this.canary),emit(\"arg.canary\",arg.canary)}" } }
然后在 mapReduce 调用中使用存储的函数:
MongoDB Enterprise replset:PRIMARY> db.maptest.mapReduce(function(){testfun(this)},function(a,b){return {a:a,b:b}},{out:{inline:1}})
{
"results" : [
{
"_id" : "arg.canary",
"value" : "tweet"
},
{
"_id" : "this.canary",
"value" : undefined
}
],
...
如您所见,this.canary
未定义,但 arg.canary
包含输入文档中的值。
mapReduce框架在调用map函数时将this
分配给当前正在检查的文档。当从映射函数内调用存储的函数时,它会获得自己的 this
。但是,通过将函数调用为 testfun(this)
, map 函数的原始 this
上下文将作为参数提供给存储的函数。
关于javascript - 如何在java中的mapReduce中调用mongodb服务器端函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60863761/