我有一个运行在集合上的MapReduce查询 - mycollection - 目前包含4个文档,每个文档都具有相同的结构:
{
myobject: {
key_field: "some_name",
one_number: 15,
other_numer: 20
},
some_more_data: {}
}
key_field 不是唯一的。在这个例子中,我有4个文件,其中 key_field:“some_name”,总共约400个。
reduce()fumction对 one_number 和 other_number 执行一些算术运算,并且应该将结果输出到新的集合( my_mapreduce_collection ):
var map = function() {
emit(this.myobject.key_field, {
field1: this.myobject.one_number,
field2: this.myobject.other_number
});
};
var reduce = function(key, values) {
var sum = 0;
values.forEach(function(doc, idx) {
//Output each iteration:
print("Key: "+key+", Idx: "+idx+" --> "+JSON.stringify(doc));
sum += (doc.field1 - doc.field2);
});
return sum;
};
var MR = {
mapreduce: "my_mongodb_collection",
out: "my_mapreduce_collection",
map: map.toString(),
reduce: reduce.toString()
};
但是,我有时会在某些 key_field 上获得 nan 值。
所以,我在 reduce()上添加了 print()函数,这就是它输出的内容:
...
密钥:some_name,Idx:0 - > { “one_number”:15, “other_number”:20}
密钥:some_name,Idx:1 - > { “one_number”:10 “other_number”:30}
密钥:some_name,Idx:0 - > 0
密钥:some_name,Idx:1 - > { “one_number”:20, “other_number”:40}
密钥:some_name,Idx:2 - > { “one_number”:25, “other_number”:50}
...
由于某种原因,我得到一个值“0”,而不是一个对象,然后索引重新启动。这只发生在一些文件上。我检查了它们,它们看起来都是同质的。
对可能发生的事情有任何想法?
谢谢!
答案 0 :(得分:1)
您正在错误地使用mapReduce。从reduce返回的值应该与从map中发出的值相同。虽然你这样做的方式看起来似乎有效,但只要你达到100条记录,你就会看到它是如何破坏的。
你的索引再次开始的原因是因为可以多次调用reduce(第二个中的第一个结果),这是我之前评论的来源。这就是为什么你得到0之间的原因,因为形状不匹配。
您应该使用finalize函数对先前减少的值求和。
var map = function() {
emit(this.myobject.key_field, {
field1: [this.myobject.one_number],
field2: [this.myobject.other_number]
});
};
var reduce = function(key, values) {
var res = {
field1: [],
field2: []
};
values.forEach(function(doc, idx) {
res.field1 = res.field1.concat(doc.field1);
res.field2 = res.field2.concat(doc.field2);
});
return res;
};