couchdb减少非键值

时间:2012-10-15 17:01:10

标签: javascript mapreduce couchdb

我在couchdb中有一个数据集,其中包含多个文档,列出时间戳和来自传感器的一组信号。在这个例子中,我只使用了几个不同的名称,但随着系统中添加了额外的传感器,可能会有无数不同的名称。以下是三个示例文档的示例:

{ timestamp: 12345,
  signals: ["highTemperature", "highPressure"]
}

{ timestamp: 12346,
  signals: ["highTemperature"]
}

{ timestamp: 12347,
  signals: ["lowPressure", "highTemperature"]
}

我希望能够获得每个标签的频率。一个简单的方法是创建一个这样的map函数:

function (doc) {
  for (var idx in doc.signals) {
  emit(doc.signals[idx], 1);
}

还有像这样的reduce函数:

function(signal, counts) {
  var sum = 0;
  for(var i = 0; i < counts.length; i++) {
    sum += counts[i]; 
  };
  return sum; 
}

这将返回一组很好的数据,如下所示:

{"rows":[
  {"key":"highTemperature","value":3},
  {"key":"highPressure","value":1},
  {"key":"lowPressure","value":1}
]}

如果我想知道所有时间的信号分布,这很好,但我真的想知道数据点子集的标签分布,比如时间戳12346-12349。但是,我不能做什么使用startkeyendkey按时间戳对数据进行切片,因为时间戳不是密钥的一部分。如果我让时间戳成为关键,那么我无法减少以获得信号分布。

有没有办法进行这样的分组,以便减少不属于密钥的元素?理想情况下,我想通过URL参数指定分组间隔,例如:/mydb/_design/main/_view/signalsByTime?startkey=12346&endkey=12347并让它返回该时间段的信号分布,如下所示:

{"rows":[
  {"key":"highTemperature","value":2},
  {"key":"lowPressure","value":1}
]}

1 个答案:

答案 0 :(得分:2)

如果您希望timestamp成为关键字,可能信号的数量非常小(O(1),假设您的示例中为3),那么您可以发出map特征你的信号矢量:

if (doc.signal == "highTemperature") {
  emit(doc.timestamp, [1,0,0]);
} else if (doc.signal == "highPressure") {
  emit(doc.timestamp, [0,1,0]);
} ...

reduce中的总结向量,可能是这样的:

function(keys, values) {
  var sum = [0,0,0];
  for (v in values) {
    for (s in sum) {
      sum[s] += values[v][s];
    }
  }
  return sum; 
}