2012-10-15 29 views
1

我有一个数据集在couchdb中有多个文档,列出了来自传感器的时间戳和一组信号。在这个例子中,我只使用了几个不同的名字,但是当系统中添加了其他传感器时,可以有无数不同的名称。下面是三个示例文档的示例:couchdb减少非键值

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

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

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

我希望能够做的是获取每个标签的频率。一个简单的方法做,这是创建一个映射函数是这样的:

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

伴随着这样的减少功能:

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} 
]} 
+0

您希望如何指定分组间隔? – Bergi

+0

编辑该问题以澄清。我想使用startkey和endkey来指定我应该聚合信号的时间戳的范围。在功能上,如果我可以让视图发出(doc.timestamp,doc.signal [idx]),然后对(value,key)集合而不是(key,value)集合运行reduce,那么这将非常简单。 – Pridkett

+0

好吧,我不擅长看法。 – Bergi

回答

2

如果你想timestamp是关键和可能的信号的数量是非常小的(O(1),让我们假设3如在实施例),那么就可以在信号的map特征向量发射:在reduce

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

及和向上向量,可能这样:

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

这是一个很好的答案,当潜在信号的集合很小时,但在我的系统集中实际上非常大,并且可以随时增长。这是一个非常好的答案,但它并不能完全解决我的问题,但主要是因为我对第一种情况的问题不够清楚。 – Pridkett

+0

你能预测关于查询的任何事情吗?也许你会选择一些范围的边界,例如一些谷物,例如时间戳总是四舍五入到分钟,范围不超过一个小时等等。动态任意查询在我看来并不是什么Couch所设计的。 –