2011-09-05 34 views
1

我对MongoDB和MapReduce相当陌生。我需要在数据库的某个集合上执行一些MapReduce。 MAPREDUCE_MAX函数起作用,因为我能够在Mongo交互式shell(v.1.8.2)中完成我的需求。但是,我得到一个错误尝试使用蒙戈Java驱动程序来执行同样的事情MapReduce使用MongoDB Java驱动失败,BSONElement断言错误类型

MAPREDUCE_MAX功能看起来像这样(V 2.6.3):

String MAP = 
      "function(){" + 
        "if(this.type != \"checkin\"){return;}" + 
        "if(!this.venue && !this.venue.id){return;}" + 
        "emit({userId:this.userId, venueId:this.venue.id}, {count:1});" + 
        "};"; 


String REDUCE_MAX = 
      "function(key, values){" + 
        "var res = {count:0};" + 
        "values.forEach(function(value){result.count += value.count;});" + 
        "return res;" + 
        "};"; 

这是我的命令中号执行:

MapReduceOutput sum = collection 
       .mapReduce(MAP, REDUCE_MAX, null, null); 

这是我的错误:

com.mongodb.CommandResult$CommandFailure: command failed [command failed [mapreduce] { "assertion" : "wrong type for BSONElement (replace) 10 != 2" , "assertionCode" : 13111 , "errmsg" : "db assertion failure" , "ok" : 0.0} 

我不知道哪个BSONElement类型错误。我已经使用了assertionCode: 13111。我也检查了MongoDB日志,但没有找到任何线索。

有没有人有一个想法,我可能会错过/做错了什么?如果你们需要更多的细节,请让我知道。

回答

4

今天我偶然发现了自己的错误,并试图在这里分享解决方案,以防万一遇到类似问题。

mapReduce方法的调用是造成问题:

MapReduceOutput sum = collection 
       .mapReduce(MAP, REDUCE_MAX, null, null); 

看一看的Javadoc此方法:

/** 
* performs a map reduce operation 
* Runs the command in REPLACE output mode (saves to named collection) 
* 
* @param map 
*   map function in javascript code 
* @param outputTarget 
*   optional - leave null if want to use temp collection 
* @param reduce 
*   reduce function in javascript code 
* @param query 
*   to match 
* @return 
* @throws MongoException 
* @dochub mapreduce 
*/ 

它指出,该命令使用REPLACE作为输出执行模式,并且如果想要临时收集,则outputTarget应该是null

不幸的是,虽然,构造MapReduceCommand,其在mapReduce方法中使用,只允许如果OutputType设置为INLINEoutputTarget为可以为空(根据MapReduceCommand.getOutputTarget()的Javadoc)。

所以我不得不做的是第三个参数从null改变一些String,就像这样:

MapReduceOutput sum = collection 
       .mapReduce(MAP, REDUCE_MAX, "tmp", null); 

这就像我没有用在试图弄清楚为什么各地发挥的唯一参数它没有工作。我希望有人会觉得这有帮助。

3

你也可能会想尝试:

MapReduceOutput sum = collection.mapReduce(MAP, REDUCE_MAX, null, 
        OutputType.INLINE, null); 

如果你想有一个内嵌收集没有给它一个名字