我一直在使用CouchDB很长一段时间没有任何问题。到现在为止。我最近在地图中看到了一些内容/缩小了我忽略的结果!
这是在“avgs”变量上执行sum
之前。我基本上试图找到与特定键有关的所有值的平均值。没有什么花哨。结果如预期。
注意时间戳1308474660000的结果(表中的第4行):
现在我sum
“avgs”数组。现在这里有一个结果特有的东西。时间戳为1308474660000的密钥总和为null
!!为什么CouchDB会为简单的null
吐出sum
个?我尝试使用自定义添加功能和同样的问题。
有人可以向我解释为什么我的map / reduce结果会出现这个问题吗?
CouchDB版本:1.0.1
更新
执行rereduce后,我得到一个reduce overflow错误!
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
两次。一旦进入减少,再次进行减少。
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.
}
}
答案 0 :(得分:2)
reduce函数中的for
循环可能没有按照您的想法执行。例如,它可能会抛出您没想到的异常。
您期待一组2元组:
// Expectation
values = [ [value1, total1]
, [value2, total2]
, [value3, total3]
];
在重新缩减期间,该函数将在之前获得旧结果。
// Re-reduce values
values = [ avg1
, avg2
, avg3
]
因此,我将首先检查代码如何在rereduce
为真时运行。也许一些简单的东西会解决它(虽然我经常需要log()
个东西才能找到问题。)
function(keys, values, rereduce) {
if(rereduce)
return sum(values);
// ... then the same code as before.
}
答案 1 :(得分:1)
我会详细说明我的点数/总和评论,以防你好奇。
此代码未经过测试,但希望您能得到这个想法。最终结果始终是一个简单的对象{"count":C, "sum":S}
,您可以通过计算S / C
来了解平均值。
function (key, values, rereduce) {
// Reduce function
var count = 0;
var sum = 0;
var i;
if(!rereduce) {
// `values` stores actual map output
for(i = 0; i < values.length; i++) {
count += Number(values[i][1]);
sum += Number(values[i][0]);
}
return {"count":count, "sum":sum};
}
else {
// `values` stores count/sum objects returned previously.
for(i = 0; i < values.length; i++) {
count += values[i].count;
sum += values[i].sum;
}
return {"count":count, "sum":sum};
}
}
答案 2 :(得分:0)
我使用以下代码进行平均。希望它有所帮助。
function (key, values) {
return sum(values)/values.length;
}