MapReduce using MongoDB Java Driver failes with wrong type for BSONElement assertion

 ̄綄美尐妖づ 提交于 2019-12-08 04:00:35

问题


I'm pretty new to MongoDB and MapReduce. I need to do some MapReduce on a collection in my DB. The MAP and REDUCE_MAX functions work, since I was able to accomplish my needs in the Mongo interactive shell (v.1.8.2). However, I get an error trying to perform the same thing using the Mongo Java Driver (v. 2.6.3)

My MAP and REDUCE_MAX functions look like this:

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;" +
                    "};";

This is the command I'm executing:

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

This is the error I get:

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}

I don't know which BSONElement has the wrong type. And I've already googled the assertionCode: 13111. I've also checked in the MongoDB log, but did not find any clues there.

Does anyone have an idea, what I could be missing/doing wrong? If you guys need more details, just let me know please.


回答1:


Today I stumbled upon my mistake and figured to share the solution here, just in case somebody encounters a similar problem.

The invocation of the mapReduce method was causing the problem:

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

Have a look at the Javadoc for this method:

/**
 * 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
 */

It states that the command is executed using REPLACE as output mode and that if one wants a temporary collection, the outputTarget should be null.

Unfortunately though, the constructorMapReduceCommand, which is used in the mapReduce method, only allows the outputTarget to be nullable if the OutputType is set to INLINE (according to the Javadoc of MapReduceCommand.getOutputTarget()).

So all I had to do is to change the third parameter from null to some String, like so:

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

This was like the only parameter I had not played around with while trying to figure out why it didn't work. I hope somebody might find this helpful.




回答2:


You might also want to try:

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

if you want to have an inline collection without giving it a name



来源:https://stackoverflow.com/questions/7306329/mapreduce-using-mongodb-java-driver-failes-with-wrong-type-for-bsonelement-asser

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!