2013-03-03 12 views
3

我有一個數據庫,用於存儲大量數據併爲圖形生成視圖。我只返回預定義數量的樣本,而不是返回圖表的所有數據。我目前這樣做的方式是在mongo上使用map/reduce作業,但我不知道我這樣做的方式是否非常有效,它需要14秒鐘,並將圖形上的CPU固定在超過89000個樣本上例。mongodb中的高效下采樣

下采樣通過計算「分辨率」來工作,即(總點數)/(期望樣本數量)。然後使用範圍變量保留並進行外部計數和索引。然後,它基本上查看每個點,並根據計數/索引變量的分辨率和當前狀態決定是否將其包含在結果列表中。

這工作正常,但相當緩慢,可能無法擴展。我想知道是否會更好,例如只返回所有的點並用紅寶石進行下采樣,或者有更好的方法。

+1

查看Mongo的新聚合框架。 http://docs.mongodb.org/manual/applications/aggregation/你可以做聚合(顯然),它比map/reduce要快得多,速度更快。 – ryan1234 2013-03-03 22:26:36

+0

謝謝,我不知道我可以在這種情況下獲得聚合工作。現在,我正在基於排序後數組中文檔的偏移量進行縮減採樣。我正在考慮一個更好的方法來做到這一點,雖然將由文件中的值x。例如,我有數據從x = 10,000到x = 100,000,000,有100,000個數據點。我想把這個縮減到只有1000點,在整個x域(10,000 - 1,000,000)中均勻分佈。什麼是最好的方法來做到這一點? – 2013-03-04 01:10:13

+0

那麼你在文檔中的數組中有100k個元素? – ryan1234 2013-03-04 02:41:56

回答

3

如果有人有興趣,這是我想出的解決方案。由於mongodb的某些限制,我花了一段時間才弄清楚,但它運行得非常好,比我當前的map reduce解決方案快了10倍。

這裏是聚合代碼:

db.data.aggregate(
    {$match: {$and: [{graph_id: gid}, {"x.value": {$gt: start, $lt: stop}}]}}, 
    {$project: {x: 1, y: 1, series: 1, chunk: {$subtract: [{$divide: ["$x.value", step]}, {$mod: [{$divide: ["$x.value", step]}, 1]}]}}}, 
    {$group: { 
    _id: { 
     chunk: "$chunk", 
     series: "$series" 
    }, 
    series: {$first: "$series"}, 
    x: {$first: "$x"}, 
    y: {$first: "$y"}, 
    } 
    }, 
    {$sort: {"x.value": 1}} 
) 

將該溶液組塊中的數據。我想要做一些像int(x.value/step),但mongodb沒有整數數學運算符。所以我不得不用((x.value/step) - ((x.value/step)%1))來僞造它,它給出了除法的整數部分。

這個效果很好,可以讓你做平均大塊的事情,而不是隻是選擇第一個,很容易。