5

Is their a way to Execute a MongoDB map reduce job through the java driver in which you create a scope DBObject that contains functions.

I can execute my map reduce configuration in javascript where the passed in scope contains utility functions, but I can't figure out how to do this with the java driver.

I setup the scope using mapReduceCommand's

c.addExtraOption("scope",new BasicDBObject().append('average',function(){ return false;}));

However I can't get the mappers/reducers to recognize the scope component 'e.g.' average as a function. If I use quotes, the map reduce context thinks its a String, but if not, I can't seem to make the scope component parse.

How does one get a function in the scope component through the java driver?

Thanks to Ren's answer, Here is a spring bean configuration to set up a scope for the mongodb java driver with a function.

    <util:map id="mrScope" 
              key-type="java.lang.String" 
              value-type="java.lang.Object">
    <entry key="buckets"><bean class="com.mongodb.util.JSON" factory-method="parse"><constructor-arg value="[0,10,15,20,25,30,35,40,45,50,55,60,65]"/></bean></entry>
    <entry key="average">
        <bean class="org.bson.types.CodeWScope">
            <constructor-arg value="function () {var s = 0;for (var i = 0; i &gt; arguments.length; i++) s += arguments[i];return s / arguments.length;}"/>
            <constructor-arg><bean class="org.bson.BasicBSONObject"/></constructor-arg>
        </bean>
    </entry>
1
  • Can you please provide more details like how to use a Map as scope object.. Is it possible ? Commented Dec 23, 2015 at 9:38

3 Answers 3

8

The server code automatically converts the map and reduce into Javascript function, but not so with scope. To pass a function in the scope option, you can do this instead:

c.addExtraOption("scope", new BasicBSONObject("average",
  new CodeWScope("function(){ return false;}", new BasicBSONObject())));
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks Ren. This part of Mongo is not as well documented as some would like :) So it is good to find the answers.
1

With the new api (3.0).. I found the below option is working

collection .mapReduce(map, reduce) .scope(new Document("key", value)) .limit(100);

Comments

1

For those who struggle with applying function in scope using MongoTemplate, example below seems to work:

    Map<String, Object> scopeVariables = new HashMap<>();
    String scopeFunction="function(){ //do something }";
    scopeVariables.put("transform", new CodeWScope(scopeFunction,new BasicBSONObject()));

    MapReduceOptions options = new MapReduceOptions();
    options.scopeVariables(scopeVariables);
    options.outputTypeInline();

    MapReduceResults<ValueObject> result = template.mapReduce("collection", mapFunction, reduceFunction, options, ValueObject.class);

After running code above, transform() function will be visible in map function:

var mapFunction=function(){  
  transform(); 
  emit(key,value); 
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.