【发布时间】:2011-09-22 01:20:57
【问题描述】:
我使用 CouchDB 已经有一段时间了,没有任何问题。直到现在。我最近在我的 map/reduce 结果中看到了一些我忽略的东西!
这是在对“avgs”变量执行sum 之前。我基本上是在尝试找到与特定键有关的所有值的平均值。没有什么花哨。结果符合预期。
注意时间戳 1308474660000(表中的第 4 行)的结果:
现在我 sum "avgs" 数组。现在这里有一些关于结果的特殊之处。时间戳为 1308474660000 的键的总和是 null!!为什么 CouchDB 为一个简单的sum 吐出nulls?我尝试了自定义添加功能,但问题相同。
有人可以向我解释为什么我的 map/reduce 结果存在这个问题吗?
CouchDB 版本:1.0.1
更新:
在执行 rereduce 后,我得到一个 reduce 溢出错误!
Error: reduce_overflow_error
Reduce output must shrink more rapidly: Current output: '["001,1,1,1,1,1,11,1,1,1,1,1,1,11,1,1,1,1,1,1,11,1,1,1,1,1,1,11,1,1,1,1,1,101,1,1,1,1,1,1,11,1,1,1,1'... (first 100 of 396 bytes)
这是我修改后的reduce函数:
function (key, values, rereduce) {
if(!rereduce) {
var avgs = [];
for(var i=values.length-1; i>=0 ; i--) {
avgs.push(Number(values[i][0])/Number(values[i][1]));
}
return avgs;
} else {
return sum(values);
};
}
更新 2:
现在情况变得更糟了。其选择性地减少。此外,它减少的那些显示错误的结果。时间戳 (1308474660000) 的第 4 行值的长度应为 2 而不是 3。
更新 3:
我终于让它工作了。我没有正确理解 rereduce 的细节。 AFAIK,Couchdb 本身决定如何/何时重新减少。在这个例子中,只要数组足够长可以处理,Couchdb 就会将它发送到 rereduce。所以我基本上不得不sum 两次。一次在reduce中,再次在rereduce中。
function (key, values, rereduce) {
if(!rereduce) {
var avgs = [];
for(var i=values.length-1; i>=0 ; i--) {
avgs.push(Number(values[i][0])/Number(values[i][1]));
}
return sum(avgs);
} else {
return sum(values); //If my understanding of rereduce is correct, it only receives only the avgs that are large enough to not be processed by reduce.
}
}
【问题讨论】:
-
跟进:我对 CouchBase/Bigcouch 进行了同样的尝试,它正确计算了时间戳的
sum,但其他键显示nulls。奇怪!