【问题标题】:MongoDB's MapReduce function in Java returns nullJava中MongoDB的MapReduce函数返回null
【发布时间】:2011-09-19 06:14:28
【问题描述】:

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

当我使用下面的 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 }

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

【问题讨论】:

  • 我认为emit()中的变量名需要映射到reduce中的变量名。
  • @JonathanHendler 我认为情况并非如此。我有同样的问题,可以从 Java 调试器中复制 db 命令,在 mongo 控制台中运行它并获得正确的结果。

标签: java mongodb mapreduce


【解决方案1】:

这是因为在你定义了 sbReduce 变量之后,你再也没有向它添加任何东西。您错误地将函数添加到 sbMap 变量中。例如,reduce 函数的第一行是:sbMap.append(...) 其中应该是 sbReduce.append(...)。

【讨论】:

    猜你喜欢
    • 2012-09-27
    • 1970-01-01
    • 2014-08-01
    • 2020-09-21
    • 2015-11-18
    • 2019-10-14
    • 2017-04-15
    • 1970-01-01
    相关资源
    最近更新 更多