2011-09-05 63 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); 

如果你想有一個內嵌收集沒有給它一個名字