CouchDB Reduce-错误仅按降序排列

时间:2012-04-26 21:34:44

标签: couchdb mapreduce

我遇到了一些问题,看起来在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,这就完美无缺。一旦设置为真,我的结果就会被中断一半。

两个问题:

  1. 为什么结果顺序对reduce函数很重要?随着减少,结果是向前和向后相同。
  2. 我在某处读过,如果你的缩减没有提供单个标量,你可能做错了。如果除了奇怪的行为这是一个糟糕的方法,从日志式数据源提供这种数据的正确方法是什么?

3 个答案:

答案 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_levelstartkey/endkey来获得有意义的结果。

答案 2 :(得分:0)

杰森的回答是优秀和正确的,但对于任何磕磕绊绊的人来说,我的根本问题是缺乏对减少如何运作的理解。

最重要的是,reduce函数的输出本身必须是可还原的,因为couchdb并行执行减少。如果你有1000行匹配一个键,沙发可能需要10组100,并将功能应用于每个。然后它将重新减少先前减少的10个输出,以得到密钥集的解决方案。

你最好阅读文档......

Read the Reduce/Rereduce Sections of the CouchDB docs