我似乎无法在任何地方找到答案,所以也许这是不允许的,但我无法找到确认这一点的任何couchdb信息。这是一个场景:
假设对于地图功能,在Futon中,我发出一个键的值,例如。 K(1)。该值由密钥K(1)的两个单独的浮点数A(1)和B(1)组成。我希望减少执行比率A(N)/ B(N)在所有K(N)上从1到N的样本平均值。我在reduce函数中总是遇到的问题是"价值观"参数。每个键与(A,B)的值对相关联,但我不能从"值"中分出A,B浮点数。我似乎无法找到有关如何执行此操作的任何示例。我已经尝试过访问"值"的多级javascript数组。但它不起作用,下面是我的地图功能。
function(doc) {
if(doc['Reqt.ID']) {
doc['Reqt.ID'].forEach(function(reqt) {
row_index=doc['Reqt.ID'].indexOf(reqt);
if(doc.Resource[row_index]=="Joe Smith")
emit({rid:reqt},{acthrs:doc['Spent.Hours'] [row_index],esthrs:doc['Estimate.Total.Hours'][row_index]});
});
}
}
如果我只生成一个在地图函数中发出单个元素值A / B的地图,我可以让它工作(即平均比率),但我对这个多值元素的情况感到好奇。这通常是如何在Futon减少功能中完成的?
我已经在密钥的for循环中尝试了各种JSON Javascript符号,例如值[key index] .esthrs [0],但我的组合都不起作用。
非常感谢你。
答案 0 :(得分:2)
有两种方法可以解决这个问题;首先,我的建议是改变你的地图功能,使它更像是“键是键,值是值”,在你的特殊情况下可能意味着,因为你有两个“值”,你想要使用, Spent.Hours
和Estimate.Total.Hours
,您需要两个观点;虽然你可以作弊,但在同一个视图中每行发出多个emit()
,例如:
emit(["Spent.Hours", reqt], doc['Spent.Hours'][row_index]);
emit(["Estimate.Total.Hours", reqt], doc['Estimate.Total.Hours'][row_index]);
使用该方法,您可以使用预定义的_stats
reduce函数。
或者,您可以定义“智能”统计功能,该功能可以对更精细的文档进行统计。
标准_stats
函数提供计数,总和,平均值和标准差。它使用的算法是取值的总和,平方值的总和和值的数量;从这些方面来看,可以计算平均值和标准偏差(并且为了方便起见,将其嵌入到简化视图中)
粗略地说,可能看起来像:
function(key, values, rereduce) {
function getstats(seq, getter) {
var c, s, s2 = 0, 0, 0;
values.forEach(function (row) {
var value = getter(row);
if (rereduce) {
c += value.count;
s += value.sum;
s2 += value.sumsq;
} else {
c += 1;
s += value;
s2 += value * value;
}
return {
count: c,
sum: s,
sumsq: s2,
average: s / c,
stddev: Math.sqrt(c * s2 - s1) / c
};
}
return {esthrs: getstats(function(x){return x.esthrs}),
acthrs: getstats(function(x){return x.acthrs})};
}