我在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。但是,我不能做什么使用startkey
和endkey
按时间戳对数据进行切片,因为时间戳不是密钥的一部分。如果我让时间戳成为关键,那么我无法减少以获得信号分布。
有没有办法进行这样的分组,以便减少不属于密钥的元素?理想情况下,我想通过URL参数指定分组间隔,例如:/mydb/_design/main/_view/signalsByTime?startkey=12346&endkey=12347
并让它返回该时间段的信号分布,如下所示:
{"rows":[
{"key":"highTemperature","value":2},
{"key":"lowPressure","value":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;
}