2

I've some test data in my MongoDB:

> db.test2.find()
{ "_id" : ObjectId("4e76ad8e9d7dc2438ab63dbb"), "name" : "John", "number" : 2 }
{ "_id" : ObjectId("4e76ad8e9d7dc2438ab63dbc"), "name" : "Jane", "number" : 1 }
{ "_id" : ObjectId("4e76ad8e9d7dc2438ab63dbd"), "name" : "John", "number" : 2 }
{ "_id" : ObjectId("4e76ad8e9d7dc2438ab63dbe"), "name" : "Jane", "number" : 1 }

And when I use following map/reduce function, MongoDB return the correct answer.

> m = function() { emit(this.name, {count: 1, sum: this.number}); }

> r = function(key, values) {
    var n = { count: 0, sum: 0};
    for (var i=0; i<values.length; i++) {
        n.sum += values[i].sum;
        n.count += values[i].count;
    }
    return n;
}

> db.test2.mapReduce(m, r, {out: 'test_col2'})
> db.test_col2.find()
{ "_id" : "Jane", "value" : { "count" : 2, "sum" : 2 } }
{ "_id" : "John", "value" : { "count" : 2, "sum" : 4 } }

But If I test a following Java program, the result value is NULL.

public void run() throws Exception {
    m = new Mongo(HOST, PORT);
    db = m.getDB("test");

    DBCollection col = db.getCollection("test2");

    StringBuilder sbMap = new StringBuilder();
    sbMap.append("function() {");
    sbMap.append("    emit(this.name, {count:1, sum:this.number});");
    sbMap.append("}");

    StringBuilder sbReduce = new StringBuilder();
    sbMap.append("function(key, values) {");
    sbMap.append("    var n = { count: 0, sum: 0};");
    sbMap.append("    for (var i=0; i<values.length; i++) {");
    sbMap.append("        n.count += values[i].count;");
    sbMap.append("        n.sum += values[i].sum;");
    sbMap.append("    }");
    sbMap.append("    return n;");
    sbMap.append("}");

    MapReduceCommand cmd = new MapReduceCommand(col, sbMap.toString(), sbReduce.toString(), null,
                    MapReduceCommand.OutputType.INLINE, null);

    MapReduceOutput out = col.mapReduce(cmd);

    for (DBObject o : out.results()) {
        System.out.println( o.toString() );
    }
}

Result:

{ "_id" : "Jane" , "value" :  null }
{ "_id" : "John" , "value" :  null }

What's the problem? I can't understand it. :(

2
  • I think the variable names in emit() need to map to variable names in the reduce. Commented Sep 28, 2011 at 18:32
  • @JonathanHendler I don't think that is the case. I have the same issue and can copy the db command out of the Java debugger, run it in the mongo console and get the correct results. Commented Dec 29, 2012 at 3:21

1 Answer 1

2

It is because after you define the sbReduce variable, you never add anything to it. You mistakenly add the function to the sbMap variable. For example, the first line of your reduce function is: sbMap.append(...) where it should be sbReduce.append(...).

Sign up to request clarification or add additional context in comments.

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.