如何使用 MongoDB 中的聚合管道
聚合管道是在 MongoDB 中運行複雜查詢的推薦方法。如果您一直在使用 MongoDB 的 MapReduce,您最好切換到聚合管道以獲得更高效的計算。
MongoDB 中的聚合是什麼以及它是如何工作的?
聚合管道,也稱為“Agg”管道,是 MongoDB 中的一種綜合查詢機制,可促進複雜的數據分析和操作。該管道利用一系列互連的階段,允許用戶利用一個階段的輸出作為後續階段的輸入,對其數據集執行各種操作。這種多功能工具使用戶能夠簡化數據處理任務,同時提高整體效率和準確性。
例如,可以將匹配過程的結果傳輸到後續階段,以便根據所述排列進行重新排列,直到獲得優選的輸出。
在聚合管道的整個過程中,每個階段都包含一個 MongoDB 組件,並生成一個或多個修改後的文檔作為輸出。特定級別在管道中出現的頻率取決於所進行的查詢的具體性質。在某些情況下,可能需要合併運算符,例如
聚合管道的階段
聚合管道在單個查詢中通過多個階段傳遞數據。有幾個階段,您可以在 MongoDB 文檔 中找到它們的詳細信息。
讓我們描述一下這方面的幾個最流行的術語。
$match 階段
該過程的初始階段允許建立精確的選擇標準,可以在啟動任何後續聚合階段之前使用該標準。通過利用這一初步步驟,人們能夠識別和隔離被認為與包含在更廣泛的聚合管道中相關的特定數據集元素。
$group 階段
分組階段利用鍵值對將信息組織成不同的類別,每個類別對應於最終報告中的一個元素。
以以下說明性銷售樣本數據為例:
利用聚合管道可以計算每個類別內的總銷售量和最高創收產品。
{
$group: {
_id: $Section,
total_sales_count: {$sum : $Sold},
top_sales: {$max: $Amount},
}
}
MongoDB 的分組功能允許根據文檔的部分來組織文檔。這是通過將 \_\ id 字段與指定鍵結合使用來實現的。當使用特定的聚合運算符(例如 \ \ sum、\ \ min、\ \ max 或 \ \_avg)時,MongoDB 會根據聚合器中描述的操作為每個組生成新穎的標識符。
$skip 階段
利用聚合管道中的“$skip”階段可以從最終結果集中省略預定數量的文檔。通常,此階段在分組階段之後使用,並用於通過排除那些不需要的文檔來簡化輸出。作為說明,如果預期將產生兩份文檔而其中一份必須被丟棄,則聚合過程將僅產生剩餘的文檔。
為了在聚合管道中加入旁路步驟,您可以在其中引入“$skip”操作。
...,
{
$skip: 1
},
$sort 階段
排序過程允許以降序或升序的方式組織信息。作為說明,人們可以選擇以遞減的數量級對前一查詢場景中的數據集進行重新排序,以辨別哪個部門表現出最高的銷售水平。
通過合併“$sort”運算符修改前面的查詢,如下所示:
...,
{
$sort: {top_sales: -1}
},
$limit 階段
使用“限制”操作有助於減少聚合管道所展示的所需輸出文檔。為了說明這個概念,請考慮應用“$limit”運算符來檢索已被識別為在前一處理階段中實現了最高銷售水平的特定部分:
...,
{
$sort: {top_sales: -1}
},
{"$limit": 1}
上述結果僅產生初始文件;該特定部分構成了收入最高的部分,因為它在排列的結果列表中佔據最高位置。
$project 階段
$project
指令通過允許指定所需字段及其相應的鍵名稱,在塑造最終輸出方面提供了一定程度的靈活性。
事實上,考慮一個不包括“$project”階段的輸出的說明性示例,可能如下所示:
為了將該項目合併到我們的管道中,我們將檢查其與“$project”標籤關聯時的外觀。要實現此集成,請執行以下步驟:
...,
{
"$project": {
"_id": 0,
"Section": "$_id",
"TotalSold": "$total_sales_count",
"TopSale": "$top_sales",
}
}
考慮到我們之前按產品類別組織數據,上述方法將生成的報告中的所有相關產品部分納入其中。此外,它保證總體銷售數據和突出顯示的暢銷商品都被整合為最終輸出的一部分,分別通過“總銷量”和“最暢銷”指標表示。
與之前的版本相比,修訂後的結果表現出更高程度的改進,展示了改進的組織和演示的清晰度。
$unwind 階段
MongoDB 中的展開階段負責解構單個文檔中包含的數組並將其轉換為多個文檔。作為說明,讓我們考慮以下示例訂單數據集:
在實現額外的聚合操作之前,利用“$unwind”階段是拆解“items”數組的有效方法。當嘗試計算數組中每個元素的匯總統計信息時,此步驟特別有用。作為說明性示例,請考慮計算各個產品產生的總收入。
db.Orders.aggregate(
[
{
"$unwind": "$items"
},
{
"$group": {
"_id": "$items.product",
"total_revenue": { "$sum": { "$multiply": ["$items.quantity", "$items.price"] } }
}
},
{
"$sort": { "total_revenue":-1 }
},
{
"$project": {
"_id": 0,
"Product": "$_id",
"TotalRevenue": "$total_revenue",
}
}
])
當然,這是前面提到的聚合查詢生成的結果的更精確的呈現:
如何在 MongoDB 中創建聚合管道
上述階段提供了對聚合管道內各種操作的應用程序流程的全面理解,包括與每個階段相關的基本查詢。
請允許我對給定文本進行更精確的表述:根據我們對前面銷售數據集的檢查,謹慎的做法是對整個聚合管道中的幾個關鍵階段進行概述。通過這樣做,我們可以全面了解將原始數據轉化為有意義的見解的過程。
db.sales.aggregate([
{
"$match": {
"Sold": { "$gte": 5 }
}
},
{
"$group": {
"_id": "$Section",
"total_sales_count": { "$sum": "$Sold" },
"top_sales": { "$max": "$Amount" },
}
},
{
"$sort": { "top_sales":-1 }
},
{"$skip": 0},
{
"$project": {
"_id": 0,
"Section": "$_id",
"TotalSold": "$total_sales_count",
"TopSale": "$top_sales",
}
}
])
最終的產品與以前遇到過的東西驚人的相似,喚起了熟悉的感覺,甚至可能有似曾相識的感覺。
聚合管道與 MapReduce
在從 MongoDB 5.0 版本開始刪除之前,在數據庫中執行數據聚合的傳統方法是使用 MapReduce。雖然 MapReduce 在 MongoDB 之外擁有一系列潛在用途,但與聚合管道相比,它通常被認為效率較低,因此需要使用外部腳本來單獨定義映射和縮減過程。
相比之下,MongoDB 中的聚合管道提供了一種獨特的方法來執行複雜的查詢,同時與其他方法相比保持更高的效率和組織性。此外,該管道還包含額外的功能,可以增強對結果輸出的定制。
從 MapReduce 到聚合管道的過渡呈現出在此過程中可能遇到的許多區別。
在 MongoDB 中提高大數據查詢效率
為了有效地處理 MongoDB 中存儲的複雜信息,優化查詢以獲得最大效率至關重要。幸運的是,聚合管道為對複雜數據集執行全面計算提供了出色的解決方案。與經常影響性能的個性化操作相反,聚合框架使用戶能夠將多個處理步驟簡化為高效、單一的管道。通過這樣做,這些繁瑣的任務可以以統一的方式以更高的速度和準確性執行。
利用索引可以顯著提高 MongoDB 中聚合操作的性能,因為它減少了流程每個階段必須掃描的數據量。