CouchDB Reduce-错误仅按降序排列

CouchDB Reduce-错误仅按降序排列,couchdb,mapreduce,Couchdb,Mapreduce,我在CouchDB 1.01中遇到了一些问题,这似乎是一个相当直截了当的问题。我的数据基本上是一份从30多家诊所里买来的药物日志,上面有一些关于药物的基本数据和时间戳。我以伪形式将一组相当普通的对象作为映射结果传递到reduce中: Key:ClinicName, Value:{"vaccine":DrugType, "stamp":TimeStamp} 我的reduce函数的目的是允许快速参考所分配的每种药物的数量 地图 function(doc) { if(doc.type=="do

我在CouchDB 1.01中遇到了一些问题,这似乎是一个相当直截了当的问题。我的数据基本上是一份从30多家诊所里买来的药物日志,上面有一些关于药物的基本数据和时间戳。我以伪形式将一组相当普通的对象作为映射结果传递到reduce中:

Key:ClinicName, Value:{"vaccine":DrugType, "stamp":TimeStamp}
我的reduce函数的目的是允许快速参考所分配的每种药物的数量

地图

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=一个特定的名称时,只要descending=false和group=true,这种方法就非常有效。一旦设置下降为真,我的结果将在大约一半时被截断

两个问题:

  • 为什么结果顺序对reduce函数很重要?禁用reduce后,前后结果相同
  • 我在某个地方读到过,如果你的归约没有提供一个标量,那么你很可能是做错了。如果撇开奇怪的行为不谈,这是一种糟糕的方法,那么从日志样式的数据源显示此类数据的正确方法是什么
    问题2的答案更简单

    “单标量”经验法则对于入门很好,但我看到许多高级应用程序使用对象的方式与您完全相同


    例如,请参阅此关于汇总对象中相关值的最新答案:

    如果您想知道每个诊所的疫苗数量(计数),,则需要在键中输入

    // pseudo-form
    Key:[ClinicName, DrugType], Value:{"stamp":TimeStamp}
    
    接下来,reduce“函数”可以是字符串
    “\u count”

    有了这个,您可以设置
    ?group_level=2
    ,每个诊所每种疫苗获得一行,以及分配的所有剂量的总和。这可能与您无关,但您可以使用
    ?group_level=1
    ,免费计算每个诊所的(所有药物的)剂量

    要获得所有诊所的疫苗总数,该视图必须仅针对药物

    // pseudo-form
    Key:DrugType, Value:{"stamp":TimeStamp}
    

    主要的一点是reduce必须始终在映射输出中相邻的行上工作。然后你可以使用
    ?group_level
    startkey/endkey
    来获得有意义的结果。

    Jason的答案非常好而且正确,但对于任何一个在这方面遇到障碍的人来说,我的根本问题是对reduce如何工作缺乏理解

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

    你最好读一下这些文件


    作为一个次要的风格点,我发现减少我的“防御性”编程可以让CouchDB变得更容易。CouchDB中的Javascript环境与浏览器不同,它充满了可能改变全局值、原型等的未知脚本。例如:
    if(vCount中的vname){
    这一点说得很好。这是我最初收集时间戳而不是简单计数的产物。一如既往的好答案。如果这种改进的设计没有改变违规行为,我会追加。谢谢!我刚刚更新了答案,指出group_level=1可能也很有用,可以计算(所有疫苗的)总剂量每个诊所都有。