Contents

MongoDB 中的 Map-Reduce 與聚合管道

要點

MapReduce 是 MongoDB 用於復雜數據操作的技術,在效率和新穎性方面已被聚合管道取代。

MongoDB 中的 MapReduce 提供了一種處理大型數據集的機制,方法是將它們劃分為較小的塊並將工作分配到集群中的多個節點上。這種方法可以有效地並行處理數據。相比之下,聚合框架依賴內置運算符對數據庫本身存儲的數據集執行過濾、排序和分組等操作。這些運算符旨在與特定數據類型一起使用,並提供比 MapReduce 中所需的定制更簡化的流程。

MongoDB 建議利用其聚合管道來優化性能,但是 MapReduce 提供了更大程度的多功能性,並且非常適合分佈式文件系統,例如 Hadoop 中的文件系統。

MapReduce 和聚合管道是用於處理 MongoDB 領域內復雜數據處理任務的兩種流行方法。雖然聚合框架代表了最新的創新,但它因其卓越的性能而贏得了讚譽。然而,仍然有一批開發人員繼續青睞 MapReduce 作為他們的首選方法,並認為熟悉性和易用性是這種偏好背後的驅動因素。

從本質上講,選擇這些複雜的查詢策略之一至關重要,因為它們都會導致相同的結果。然而,了解它們的基本機制、區別和最佳用法至關重要。

MapReduce 在 MongoDB 中的工作原理

映射和縮減。

在 MongoDB 環境中使用 MapReduce 時,我們將通過使用 JavaScript 獨立地描述映射和歸約操作,並將它們分別合併到固有的 MapReduce 查詢構造中。

映射函數用於將傳入信息解析為鍵值對,這通常基於預定義的分類。正是在這一時刻,人們需要確定對數據進行分組的方法。隨後,reduce 函數對與每個數據集關聯的值執行定制計算,並將結果編譯到數據庫中維護的單獨存儲庫中。

聚合管道在 MongoDB 中如何工作

MongoDB 的聚合管道是 MapReduce 的更高級替代品,使用戶能夠在數據庫本身內執行複雜的計算和數據操作。 MapReduce 需要專門設計特定的 JavaScript 函數來優化查詢效率,與此相反,聚合過程消除了這一要求,從而在保持高性能的同時簡化了功能。

該方法不依賴外部庫進行數據操作,而是利用 MongoDB 內置運算符的功能來執行分組和計算等操作。然後將結果分組到聚合管道中,從而在構建最終輸出方面提供高度的靈活性。

MapReduce 和聚合之間的查詢有何不同

為了使用具有數據聚合功能的 MapReduce 框架確定各種產品類別的總銷售數據,產品類別充當唯一標識符或“鍵”,而單個商品銷售的小計則構成每個相應鍵的關聯“值”。

給定特定的問題陳述和隨附的數據集,提供具有代表性的數據樣本通常有助於說明其特徵和結構。在提供的問題陳述的情況下,一組假設的原始數據可能如下所示:pythonimport pandas as pdfrom sklearn.model_selection import train_test_splitfrom sklearn.ensemble import RandomForestClassifierfrom sklearn.metrics import precision_scoredf=pd.read_csv(‘data.csv’) # 從CSV 文件中讀取數據幀X=df[[‘feature1’,‘feature2’]] # 選擇相關特徵y=df[’target’] # 目標變量train_size=int(0.8 * len(df)) # /bc/images/sample-data-mongodb.jpg

我們可以通過結合使用 MapReduce 框架和聚合管道來解決這個問題,因為它將允許我們區分查詢和解決問題技術的差異。

MapReduce 方法

使用Python作為編程基礎,上述問題情況的MapReduce實現採用以下形式:

 import pymongo

client = pymongo.MongoClient(
    "mongodb://localhost/"
)

db = client.my_database

sales = db["sales"]

map_function = """
function() {
    emit(this.Section, this.Sold);
}
"""

reduce_function = """
function(key, values) {
    return Array.sum(values);
}
"""

result = db.command(
    "mapReduce",
    "sales",
    map=map_function,
    reduce=reduce_function,
    out="section_totals"
)

doc = [doc for doc in db.section_totals.find()]
print(doc)

在初始數據集上執行此操作後,後續輸出將呈現與以下類似的模式:

 [{
  '_id': 'Adidas',
  'value': 9.0
},{
  '_id': 'Nike',
  'value': 12.0
}] 

經過仔細檢查,我們可以發現該腳本中的 Map 和 Reduce 處理器被封裝為 JavaScript 函數,包含在 Python 變量中。這些變量隨後被傳遞到 MapReduce 查詢,該查詢將它們定向到由名稱“section\_totals”表示的已分配輸出集合。

使用聚合管道

與原始方法相比,合併聚合管道會產生更加簡化和直接的結果。下面說明了利用聚合管道的上述過程:

 import pymongo
client = pymongo.MongoClient("mongodb://localhost/")
db = client.funmi
sales = db["sales"]

pipeline = [
    {
        "$group": {
            "_id": "$Section",
            "totalSold": { "$sum": "$Sold" }
        }
    },
    {
        "$project": {
            "_id": 0,
            "Section": "$_id",
            "TotalSold": "$totalSold"
        }
    }
]

result = list(sales.aggregate(pipeline))
print(result)

執行此聚合操作預計會產生與通過 MapReduce 方法獲得的結果非常相似的結果:

 [{
  'Section': 'Nike',
  'TotalSold': 12
},{
  'Section': 'Adidas',
  'TotalSold': 9
}] 

查詢性能和速度

MongoDB 提倡利用其先進的聚合管道而不是傳統的 MapReduce,因為它提高了效率並簡化了功能。

我們在上一節中進行了一項實驗,試圖通過在配備 12 GB RAM 的計算機上同時執行查詢來證實我們的主張。結果表明,聚合管道的執行效率更高,平均執行時間僅為 0.014 秒。相比之下,同一系統處理 MapReduce 查詢大約需要 0.058 秒。

雖然這可能不是準確的性能衡量標準,但數據似乎支持 MongoDB 的建議。當考慮單個查詢時,這種差異的影響似乎可以忽略不計;然而,其累積效應在數量眾多(從數千到數百萬)的請求中變得相當大。

MapReduce 的優點和缺點

評估MapReduce的優缺點,以確定其在數據處理方面的優勢。

優點

通過利用映射和化簡函數的單獨實現,Apache Spark 的 RDD 提供了更高程度的適應性,使用戶能夠根據特定要求定制其處理管道。

利用該應用程序與 MongoDB 的無縫集成,用戶可以輕鬆地將生成的輸出存儲在數據庫中新創建的集合中。

MapReduce 是一個功能強大的工具,可以在分佈式文件系統(例如 Hadoop 中的文件系統)中使用,以與 MongoDB 無縫集成。

它與外部腳本語言(例如 JavaScript)兼容的優勢增強了其可擴展性和可訪問性,使具有編程經驗的個人更容易有效地應用 MapReduce 概念。

缺點

利用外部腳本資源是該方法實現的先決條件,與聚合管道相比,這不可避免地導致效率下降。

MapReduce 雖然是處理分佈在多台機器上的大量數據的有效解決方案,但在處理需要高計算能力的複雜數據集時可能會出現內存效率問題。這通常需要利用大量計算節點來有效地管理和處理此類信息。

處理實時數據可能會帶來某些挑戰,因為與非實時場景相比,查詢可能會受到性能較慢的不利影響。

聚合管道的優缺點

更詳細地檢查聚合管道,考慮其優點和缺點,可以更深入地了解其功能。

優點

探究本質上往往是多方面的,其特點是簡潔、清晰和易於理解。

與傳統的 MapReduce 方法相比,聚合管道的實現展示了令人印象深刻的效率提升,從而帶來了顯著的性能提升。

該應用程序擁有一套全面的集成 MongoDB 運算符,使用戶能夠構建具有卓越多功能性和適應性的查詢。

⭐支持實時數據處理。

聚合管道與 MongoDB 的集成可以無縫完成,無需依賴外部腳本或軟件。

如果您需要保留生成的結果,您可以選擇在 MongoDB 數據庫中建立一個全新的集合來存儲它們。

缺點

與 Apache Spark 的 MapReduce 模型相比,Flink 處理數據的方法存在局限性,因此在處理複雜的數據結構時可能無法表現出相同水平的適應性和多功能性。這是因為它依賴於流處理而不是利用外部腳本語言進行數據聚合,這限制了可用於數據操作的方法的範圍。

有效利用和理解 MongoDB 實現的複雜性所需的熟練程度可能會給剛接觸該數據庫系統、缺乏事先接觸其特性和功能的程序員帶來巨大的障礙。

什麼時候應該使用 MapReduce 或聚合管道?

/bc/images/question-mark-logos-with-code.jpg

在確定是使用 MapReduce 還是聚合管道進行數據處理時,建議仔細評估當前項目在數據處理要求方面的具體需求。

當處理複雜的數據集時,MapReduce 提供了理想的解決方案,這些數據集需要在分散的文件管理系統中進行複雜的邏輯操作和算法過程。通過定制 MapReduce 函數以滿足特定要求並將其分佈在多個計算單元上,人們可以有效地水平擴展其數據處理任務,而不是優先考慮性能優化。

相比之下,聚合管道擅長處理不需要定制推理或方法的複雜信息。當您的數據完全存儲在 MongoDB 中時,由於聚合管道具有廣泛的集成操作,因此使用聚合管道成為一個合理的選擇。

當計算效率至關重要時,聚合管道為實時數據處理提供了卓越的解決方案。在這種情況下,建議將其作為首選選項。

在 MongoDB 中運行複雜計算

MongoDB 採用兩種不同的方法來執行大數據處理操作,雖然每種方法都有其獨特的特徵,但它們之間存在一些值得注意的差異。與在進行計算之前預檢索數據的傳統做法相比,這可能會導致性能降低,而這些技術選擇直接根據數據庫本身內的信息進行計算。這種直接計算方法可以更加簡化查詢執行,從而提高整體效率。

雖然聚合管道在速度和效率方面確實往往優於 MapReduce,但值得注意的是,在某些情況下,使用 MapReduce 可能是更合適的選擇。儘管如此,由於聚合管道的卓越性能,盡可能優先使用聚合管道是理想的選擇。