2014-02-28 24 views
1

我試圖使用Map/Reduce來完成部分合併到一個現有的集合。我有MR正常工作,但有麻煩返回合併結果。MongoDB MapReduce不需要返回整個集合

這裏是與降低輸出型MR的統計:

{ 
    "result" : "calculation", 
    "timeMillis" : 222, 
    "counts" : { 
     "input" : 492, 
     "emit" : 920, 
     "reduce" : 64, 
     "output" : 435078 
    }, 
    "ok" : 1.0 
} 

我希望輸出爲實際合併文檔的數量,而不是整個集合。有沒有辦法做到這一點?

我試圖將修改:true標誌合併到目標文檔中。通過這種方式,可以進行查詢,僅返回目標集合中已修改的文檔。查詢後,我將標誌設置爲false。

雖然這個工作正常,但它開始顛簸索引,因爲大量的更改被反轉,所以HD速率開始上升,MR性能直線下降。

理想情況下,從C#驅動程序中調用result.GetResults()將自然返回由MR修改的文檔,而無需使用標誌。

更新:

具體來說,我有一個集合,是「只寫」,其中MR運行在合併成一個「讀」的集合。

是否有一個文檔設置像

{ 
    "_id":BsonId, 
    "key":"key1", 
    "valarray":["one"], 
}, 
{ 
    "_id":BsonId 
    "key":"key2" 
    "valarray":["one"] 
} 

然後MR到空白的查詢集合將產生

{ 
    "_id":"key1", 
    "value": 
    { 
    "valarray":["one"] 
    } 
}, 
{ 
    "_id":"key2", 
    "value": 
    { 
    "valarray":["one"] 
    } 
} 

和我預料的計數將是:輸入= 2,發出= 2,reduce = 0,輸出= 2

如果接着有一個新文檔插入到寫集合中

{ 
    "_id":BsonId, 
    "key":"key1", 
    "valarray":["two"], 
} 

則地圖-減少集合將是

{ 
    "_id":"key1", 
    "value": 
    { 
    "valarray":["one", "two"] 
    } 
}, 
{ 
    "_id":"key2", 
    "value": 
    { 
    "valarray":["one"] 
    } 
} 

計數被再:輸入= 1時,發射= 1,減少= 1,輸出= 2

並通過C#驅動器,調用result.GetResults()將遍歷整個目標集合。問題是我不想迭代集合,我只想遍歷由MR修改的目標集合中的文檔。在這種情況下,它應該返回「_id」:「key1」而不是「_id」:「key2」。

+0

那麼你的問題到底是什麼?也許你可以展示你正在嘗試解決的問題,你的mapReduce代碼以及你正在嘗試使用的不同文檔的樣本。 –

+0

謝謝,更新足夠了嗎? – mikkelfishman

+0

它確實顯示你想要去的地方。但只有代碼顯示你如何到達那裏以及哪裏不夠。但據猜測,目前無法知道哪些項目實際存在於您的目標中,以便確定要更新或插入的內容。 –

回答

0

問題的概括。您要合併的文檔數量相對較少,但這是對整個集合進行了。你不想要它。

的東西在這裏將要應用減少過度不僅在已經存在的文件從輸入階段,但當然產生的輸出文檔功能。所以實現似乎是在整個輸出集合上運行reduce,以便與結果合併。

所以你想要的是一個有針對性的結果,其中只有更新文件實際上被修改。有一種方法我可以看到實現這一點,但它將採取一些步驟。還有一點代碼。

  1. 運行您的常規mapReduce操作。但不是指導輸出到您的目標集合,輸出到臨時輸入集合。

  2. 使用從輸出的鍵從你的目標所需修改的文檔,並將這些成臨時目標集合。

  3. 運行修改的MapReduce,是以臨時輸入並通過與臨時目標藏品適用您的減少功能。這部分正在完成你想要的工作,但只對要更新的項目以及更小的集合進行。

  4. 一旦修改,採取該輸入並適用於您的主要目標更新操作。

所以一旦想這樣,那麼你有一個解決方法,以獲得在目標你想要的結果,而不做所有的顛簸在所有集合文件輸出級。權衡取決於額外的步驟,但收益似乎超過了一步完成這一過程所帶來的性能問題。