使用CouchDb map/reduce更快地实现不同阵列组件的最小值和最大值?

使用CouchDb map/reduce更快地实现不同阵列组件的最小值和最大值?,couchdb,mapreduce,Couchdb,Mapreduce,我有一个CouchDB数据库,其视图的值是形式为[x,y]的成对数字。对于具有相同密钥的文档,我需要(同时)计算x的最小值和y的最大值。我正在使用的数据库包含大约50000个文档。构建视图需要几个小时,这似乎有些过分。(键本身是三个数组的长度。)我在下面展示了map和reduce函数,但基本问题是:如何加快这个过程 请注意,内置函数不起作用,因为值必须是数字,而不是两个数组的长度。我可能会创建两个不同的视图(一个用于最小值(x)和一个用于最大值(y)),但我不清楚如何组合它们以同时获得两个结果

我有一个CouchDB数据库,其视图的值是形式为[x,y]的成对数字。对于具有相同密钥的文档,我需要(同时)计算x的最小值和y的最大值。我正在使用的数据库包含大约50000个文档。构建视图需要几个小时,这似乎有些过分。(键本身是三个数组的长度。)我在下面展示了map和reduce函数,但基本问题是:如何加快这个过程

请注意,内置函数不起作用,因为值必须是数字,而不是两个数组的长度。我可能会创建两个不同的视图(一个用于最小值(x)和一个用于最大值(y)),但我不清楚如何组合它们以同时获得两个结果

我当前的map函数基本上如下所示

function(doc) {
  emit ([doc.a, doc.b, doc.c], [doc.x, doc.y])
}
我的reduce函数看起来像

function(keys, values) {
  var x = null;
  var y = null;
  for (i = 0; i < values.length; i++) {
    if (values[i][0] == null) break;
    if (values[i][1] == null) break;
    if (x == null) x = values[i][0];
    if (y == null) y = values[i][1];
    if (values[i][0] < x) x = values[i][0];
    if (values[i][1] > y) y = values[i][1];
  }
  emit([x, y]);
}
功能(键、值){
var x=null;
var y=null;
对于(i=0;iy)y=值[i][1];
}
发射([x,y]);
}

这是两个因素的组合。在上面发布的代码中,一个很明显,当它应该使用“return”时,使用“emit”

另一个因素不太明显,只有通过制作数据库的较小版本并将步骤记录在reduce函数中才能发现。虽然“values”中的条目是指整数,但CouchDB将它们视为字符串。使用parseInt函数纠正了这个问题


在这两次修复之后,简化视图的整个构建过程大约需要五分钟,因此速度问题就消失了。

只需再做两次注释。使用Math.max()和Math.min()应该快一点

function(keys, values) {
  var x = -Infinity,
      y = Infinity;
  for (var i = 0, v; v = values[i]; i++) {
    x = Math.max(x, v[0]);
    y = Math.min(y, v[1]);
  }
  return [x, y];
}
如果CouchDB将这些值视为字符串,那是因为您将它们作为字符串存储在文档中


希望有帮助。

请检查。这可能会扩展到您的应用程序。

我没有尝试Math.max,因为我不确定它如何处理null。(我在R中做了很多工作,其中与null最接近的等价物是NA,它吸收了算术运算中的所有数字。)然而,运行一个测试可以确认Math.max忽略null,在这里也是如此。不完全如此。max不会忽略null,而是将其视为0。例如:“Math.max(null,1)==1”,“Math.max(null,-1)==0”。以下所有测试均为真:“-1-1”和“null>=0”。这就是为什么我使用-无穷大作为起始值。