2012-06-28 112 views
0

我有幾個我正在運行mapreduce的Mongoid模型,並且我想將統一結果存儲在一個單一的daily_stats集合中。我的地圖&減少功能正常工作的所有3種型號,但通過collection.mapreduce(map, reduce, {:out => "daily_stats", :raw => true})輸出甚至當,隨後地圖的結果減少操作覆蓋以前的結果,即使它不具有重疊鍵:在MongoDB中共享mapreduce結果集合

{'_id': "2012-06-01", 'values': {photos: 10}} 
{'_id': "2012-06-02", 'values': {photos: 10}} 

photos拋出了當後續通返回:

{'_id': "2012-06-01", 'values': {comments: 1}} 
{'_id': "2012-06-02", 'values': {comments: 6}} 

我試着用collection.mapreduce(map, reduce, {:out => {:merge => "daily_stats"}, :raw => true})也合併,但似乎沒有任何工作。

任何想法?

UPDATE

地圖&減少功能是這樣的每個模型:

地圖:

function() { 
    day = Date.UTC(this.created_at.getFullYear(), this.created_at.getMonth(), this.created_at.getDate()); 
    emit(day, {users: 1}); 
    }; 

減少: 功能(鍵,值){ VAR users_added_count = 0;

values.forEach(function(v) { 
     users_added_count += parseInt(v['users']) || 0; 
    }); 

    return {users: users_added_count}; 
    } 

下面是關於生成的架構的一些額外的信息:

{ "_id" : 1337040000000, 
"value" : { 
    "apartments" : 280, 
    "price" : 1003653, 
    "photos" : 83, 
    "comments" : 0 } 
} 
+0

有什麼原因,你沒有和/或不能運行圖減少一次,併發出一個單一的文件,即:發射(日,{users:1},{photos:1},{comments:1})? – Jenna

+0

哦,我明白了。您最初有三個獨立的集合 - 一個用於用戶,照片和評論?我將寫一個示例來說明合併數據的方式。 – Jenna

+0

或者是來自「結果模式」的文檔您的輸入數據模型?對不起,澄清一下,你能提供更多的數據例子嗎? – Jenna

回答

1

如果你看一下MongoDB的文檔映射精簡(http://www.mongodb.org/display/DOCS/MapReduce# MapReduce-Outputoptions),你會發現默認情況下,MR輸出集合會替換任何具有相同名稱的現有集合。 「合併」將新數據添加到舊輸出集合中,但用相同的密鑰覆蓋文檔。

看起來你的關鍵是日期?如果

{'_id': "2012-06-01", 'values': {photos: 10}} 

{'_id': "2012-06-01", 'values': {comments: 1}} 

具有相同的密鑰,當您運行MR第二個文件將取代第一。您需要指定一個更加獨特的密鑰,或者您需要有多個輸出集合(可能是一個用於照片,另一個用於評論?)。

+0

正確,關鍵是日期。沒有辦法將項目與相同的密鑰合併?有點像'$ addToSet'對數組字段有用嗎? – Avishai

+0

由於每個文檔都必須有一個唯一的_id字段(爲了在文檔上創建唯一的索引並跟蹤文檔的位置),因此不可能將文檔與相同的關鍵字合併;不過,我認爲你的解決方案涉及到map reduce中的finalize函數。如果您提供有關MR功能和數據架構的其他信息,我可能會提供幫助。 – Jenna

+0

當然,我添加了我的地圖和減少用戶。其他模型幾乎相同。 – Avishai

0

您可以用哈希鍵發射,使其具有唯一在你的模型

emit({day: day, type: '<model class name>'}, 1);