2011-09-19 118 views
2

我有一些测试数据在我的MongoDB:MongoDB中的MapReduce函数返回空值

> 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 } 

而且当我用下面的map/reduce功能,MongoDB的返回正确的答案。

> 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 } } 

但是,如果我测试下面的Java程序,结果值为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()); 
    } 
} 

结果:

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

什么问题? 我无法理解它。 :(

+0

我认为在emit()中的变量名称需要映射到变量名称中的reduce。 –

+0

@JonathanHendler我不认为我有同样的问题,可以从Java调试器复制db命令,在mongo控制台中运行它,并获得正确的结果。 –

回答

2

这是因为你定义sbReduce变量之后,你永远不添加任何东西给它您错误的功能添加到sbMap变量例如,您减少函数的第一行是:。sbMap .append (...)它应该是sbReduce .append(...)。