我遇到了一些问题,看起来在CouchDB 1.01中解决了一个相当直接的问题。我的数据基本上是30个奇数诊所的药物记录,其中包含一些关于药物的基本数据和时间戳。我将一组相当普通的对象作为映射结果传递给伪形式的reduce:
Key:ClinicName, Value:{"vaccine":DrugType, "stamp":TimeStamp}
我的减少功能的目的是允许快速参考分配的每种药物的数量。
地图
function(doc) {
if(doc.type=="dose"){
emit(doc.clinicName, {"vaccine":doc.vaccine,"stamp":doc.timestamp});
}
}
减少
function(keys, values){
var indexes = Object.keys(values);
var vCount = new Object;
for (var c in indexes){
var val = values[c]
var vname = val.vaccine
if(vCount.hasOwnProperty(vname)){
vCount[vname] = vCount[vname] + 1;
}
else{
vCount[vname] = 1;
}
}
return vCount;
}
当我使用?key =特定的ClinicName时,只要descending = false和group = true,这就完美无缺。一旦设置为真,我的结果就会被中断一半。
两个问题:
答案 0 :(得分:1)
问题2的答案更容易。
“单标量”经验法则适用于入门,但我看到许多高级应用程序使用与您完全一样的对象。
例如,请参阅最近关于汇总对象中相关值的答案:https://stackoverflow.com/a/10082894/2938
答案 1 :(得分:1)
如果您想知道每个诊所的疫苗数量(计数),那么您需要在密钥中使用。
// pseudo-form
Key:[ClinicName, DrugType], Value:{"stamp":TimeStamp}
接下来,您的reduce“function”可以只是字符串"_count"
。
有了这个,您可以设置?group_level=2
,每个疫苗每个疫苗获得一排,并分配所有剂量的总和。这可能与您无关,但您可以免费获得每个诊所用?group_level=1
计算剂量(所有药物)的能力。
要获得所有诊所的总疫苗数量,该观点必须仅限于该药物。
// pseudo-form
Key:DrugType, Value:{"stamp":TimeStamp}
主要观点是,reduce必须始终对映射输出中相邻的行彼此相邻。然后,您可以使用?group_level
或startkey/endkey
来获得有意义的结果。
答案 2 :(得分:0)
杰森的回答是优秀和正确的,但对于任何磕磕绊绊的人来说,我的根本问题是缺乏对减少如何运作的理解。
最重要的是,reduce函数的输出本身必须是可还原的,因为couchdb并行执行减少。如果你有1000行匹配一个键,沙发可能需要10组100,并将功能应用于每个。然后它将重新减少先前减少的10个输出,以得到密钥集的解决方案。
你最好阅读文档......