2012-10-15 81 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所設計的。 –