find() 撈回 Node.js 的記憶體裡,再用 for 迴圈慢慢加總嗎?絕對不行,你的伺服器會當場爆炸。想像一條「工廠輸送帶」。
原始資料 (Raw Data) 從入口送進來,接著會經過一連串的「加工關卡 (Stages)」。
第一關先把不要的瑕疵品挑掉,第二關把剩下的商品分類裝箱,第三關貼上重量標籤,第四關按照重量排序... 最後出來的,就是一份完美的統計報表。
這完全等同於 SQL 裡的 WHERE + GROUP BY + SUM() + ORDER BY 組合技。
在 MongoDB 裡,最常用的關卡有這五個:
$match (篩選):類似 SQL 的 WHERE。用來過濾資料,通常放在輸送帶的第一關,提早剃除不要的資料以節省效能。$group (分組):類似 SQL 的 GROUP BY。把某個欄位值相同的資料分在同一組,並支援各種數學計算 (如總和 $sum、平均 $avg、最大值 $max)。$sort (排序):類似 SQL 的 ORDER BY。將處理好的資料由大到小 (-1) 或由小到大 (1) 排序。$project (投影/塑型):類似 SQL 的 SELECT。決定最後輸出的報表只要顯示哪些欄位,甚至能把欄位重新命名。$limit (限制筆數):只取前 N 筆資料(常與 $sort 搭配用來做排行榜)。假設我們資料庫裡有一個 battle_logs (戰鬥紀錄) 的 Collection,裡面存著每次玩家挑戰關卡的結果。
原始資料長這樣:
[
{ "playerName": "Bibo", "weapon": "大劍", "damage": 5000, "isCleared": true },
{ "playerName": "Alice", "weapon": "弓箭", "damage": 3200, "isCleared": true },
{ "playerName": "Bibo", "weapon": "大劍", "damage": 4500, "isCleared": false },
{ "playerName": "Charlie", "weapon": "魔法書", "damage": 8000, "isCleared": true }
]
任務目標:
「找出所有通關成功 (isCleared: true) 的紀錄,並依照使用的武器 (weapon) 進行分組,計算出每種武器的總輸出傷害與使用次數,最後依總傷害由高到低排序。」
在 Node.js 中使用 Mongoose 實作:
import mongoose from 'mongoose';
// 假設 BattleLog Model 已經建立好
// const BattleLog = mongoose.model('BattleLog', schema);
const getWeaponDamageRanking = async () => {
try {
// 使用 .aggregate() 並傳入一個陣列 (代表輸送帶的各個關卡順序)
const report = await BattleLog.aggregate([
// 第 1 關:$match - 只挑選通關成功的紀錄
{
$match: { isCleared: true }
},
// 第 2 關:$group - 依照武器種類分組,並計算總和
{
$group: {
_id: "$weapon", // 分組的依據 (注意欄位名稱前面要加 $)
totalDamage: { $sum: "$damage" }, // 將每筆資料的 damage 累加
usageCount: { $sum: 1 } // 每出現一筆就 +1 (計算次數)
}
},
// 第 3 關:$sort - 依照剛算出來的 totalDamage 由高到低 (-1) 排序
{
$sort: { totalDamage: -1 }
},
// 第 4 關:$project - 美化輸出的欄位名稱
{
$project: {
_id: 0, // 隱藏預設的 _id
weaponName: "$_id", // 把原本分組的 _id 換個好懂的名字
totalDamage: 1, // 顯示這個欄位
usageCount: 1 // 顯示這個欄位
}
}
]);
console.log(" 武器傷害排行榜:", report);
// 預期輸出結果:
// [
// { weaponName: "魔法書", totalDamage: 8000, usageCount: 1 },
// { weaponName: "大劍", totalDamage: 5000, usageCount: 1 },
// { weaponName: "弓箭", totalDamage: 3200, usageCount: 1 }
// ]
} catch (error) {
console.error("生成報表失敗:", error);
}
};
聚合管道是 MongoDB 在應對大數據分析時的超級武器。當前端向你討要各種奇形怪狀的統計圖表資料時,熟練掌握 Pipeline 就能讓資料庫在底層高速幫你算好一切,Node.js 只要負責把精美的結果 JSON 丟給前端即可。