2014-07-19 81 views
3

我是MongoDB的初學者,我只是想知道Map-Reduce中MongoDB的Finalize函數/步驟的功能是什麼。我們在finalize()函數中所做的所有事情實際上都可以在reduce函數中完成。我只是想知道是什麼迫使我們使用finalize。我對此進行了研究並沒有發現任何東西。非常感謝您的幫助完成MongoDB Map-Reduce步驟

回答

5

其中一個最大的原因是在最後一組數據上完成所有事情之後,執行完成。不僅如此,最終確定也可以在單個結果上運行,而減少將跳過單個結果。

如果您可以盡一切辦法減少然後使用減少,您不需要最終確定。

3

雖然我知道這個問題被問和3年前回答,我有同樣的問題,並推斷未來的Google可能會發現這個額外的信息有所幫助:reduce()可稱爲multiple times使用相同的密鑰,有些傳給值它是由以前的reduce()調用返回的。這可能是因爲該集合沒有按相關密鑰,incremental Map-Reduce,parallel execution等進行排序。這就是爲什麼reduce()應該始終返回與emit()相同類型的值的原因,例如map()

所以我們說你map功能只是發出每個文檔單號,你使用你reduce函數來計算每個鍵的總和,平均:

function reduce(key, values) { 
    var resultObj = { 
     sum: Array.sum(values) 
    }; 

    resultObj.average = result.sum/values.length; 
    return resultObj; 
} 

在這種情況下,你的代碼的行爲錯誤地如果它通過一個包含resultObj的數組,因爲我不確定當Array.sum()傳遞一個數字和對象的對象時會發生什麼。即使這不是問題,此代碼將忽略任何以前計算的平均值並返回不正確的結果。另一方面,只調用一次,所以它可以返回任何想要的內容,並且(如接受的答案所述)在所有數據處理完畢後運行。所以爲了正確地完成上述工作,不要在地圖階段只發出一個數字,而應該發出類似{ sum: myVal, count: 1 }的東西。然後你reduce功能是:

function reduce(key, values) { 
    var resultObj = { 
     sum: 0, 
     count: 0 
    }; 

    for (var i in values) { 
     resultObj.sum = resultObj.sum + values[i].sum; 
     resultObj.count = resultObj.count + values[i].count; 
    } 

    return resultObj; 
} 

...然後最後你可以計算finalize平均:

function finalize(key, reducedValue) { 
    return { 
    sum: reducedValue.sum, 
    average: reducedValue.sum/reducedValue.count 
    }; 
} 
+0

這是一個很好的解釋 – pinturic

相關問題