2014-11-24 77 views
0

我有一個在MongoDB中的文檔集合,我想計算一些屬性的CDF並將其返回或存儲在數據庫中。很顯然,爲每個文檔添加一個新屬性並不是一個好方法,我可以稍後使用一個近似值。這更多的是一個理論問題。使用MapReduce在MongoDB中的累積分佈

所以我決定用計算CDF的離散間隔採樣與MapReduce工作,像這樣(只是算法):

  1. 獲取countminmax屬性someAttr
  2. 假設min = 5max=70count = 200
  3. map()for (i=this.someAttr; i < max+1; i++) { emit(i, 1) }
  4. reduce()只是返回每個鍵的總和。
  5. finalize()中,將減少的輸出除以記錄計數:return val/count

這確實輸出,但是從CDF樣本,收集..

正如你在這裏看到的間隔步驟是1,但這種方法的巨大效率低下是有可能的滔天量即使只有一小部分文檔,甚至可以從單個文檔中發佈,因此這顯然不具有可擴展性,並且不起作用。

輸出看起來是這樣的:

{ _id: 5, val: 0} 
{ _id: 6, val: 0.04} 
{ _id: 7, val: 0.04} 
... 
{ _id: 71, val: 1.0} 

在這裏,我可以輕鬆地獲得CDF的近似值爲任意值,甚至它們之間的插值,如果這是合理的。

有人能告訴我你將如何用MapReduce(或可能沒有MapReduce)計算CDF(樣本)?

回答

1

根據定義,一個屬性a累積分佈函數F_a

F_a(x) = # documents with attribute value <= x/# of documents 

定義所以,你可以計算CDF與

F_a(x) = db.collection.count({ "a" : { "lte" : x })/db.collection.count({ "a" : { "$exists" : true } }) 

計數分母假設你不想要統計丟失a字段的文檔。 a上的索引將使這個速度更快。

您可以使用它來計算cdf的樣本或只是按需計算cdf。不需要map-reduce。

+0

謝謝,顯然沒有跨越我的想法:)我忘了提及我需要整個示例數組,以便在mapreduce內部進一步使用,所以我基本上不需要'on demand'CDF for文檔。如果我用這個構建陣列,你的解決方案當然會更好,這就是我現在要做的。 我還在想,如果數據集太大或者樣本需要更精細的時間間隔,是否可以使用mapreduce來完成。我的意思是說mapreduce方法比很多方法要好(假設MR中有一個合理的算法)。 – tamacun 2014-11-25 08:12:03