Java中MongoDB的MapReduce函数返回null
我的 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 }
有什么问题吗? 我无法理解。 :(
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. :(
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
这是因为在定义 sbReduce 变量之后,您就不再向其中添加任何内容。您错误地将函数添加到 sbMap 变量。例如,reduce 函数的第一行是:sbMap.append(...),它应该是sbReduce.append(...)。
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(...).