ใช้ Aggregation Pipeline $unwind + $group + $sum
เมื่อมีอาร์เรย์ของ Sub-documents และต้องการรวมค่าของฟิลด์เฉพาะในทุก Sub-document ให้ Unwind ก่อนแล้วค่อย Group Sum
ตัวอย่างข้อมูล: คะแนนผู้เล่น
> db.sumEveryFieldDemo.insertOne({
"_id": 101,
"PlayerDetails": [
{"PlayerName":"John","PlayerScore":1000},
{"PlayerName":"Carol","PlayerScore":2000},
{"PlayerName":"Sam","PlayerScore":3000}
]
});
Pipeline: รวม PlayerScore ทั้งหมด
> db.sumEveryFieldDemo.aggregate([
{ $unwind: "$PlayerDetails" },
{ $group: {
_id: "$_id",
sum: { $sum: "$PlayerDetails.PlayerScore" }
}}
]).pretty();
ผลลัพธ์
{ "_id" : 101, "sum" : 6000 }
คำอธิบายขั้นตอน
$unwind: "$PlayerDetails": แยกอาร์เรย์ PlayerDetails ออกเป็น 3 เอกสารย่อย- แต่ละเอกสารย่อยมีฟิลด์
PlayerDetails.PlayerScore $group: รวมกลับตาม_idและ$sumคะแนนทั้งหมด
ขยาย: รวมหลายฟิลด์พร้อมกัน
db.sumEveryFieldDemo.aggregate([
{ $unwind: "$PlayerDetails" },
{ $group: {
_id: "$_id",
totalScore: { $sum: "$PlayerDetails.PlayerScore" },
totalGames: { $sum: 1 },
avgScore: { $avg: "$PlayerDetails.PlayerScore" },
maxScore: { $max: "$PlayerDetails.PlayerScore" },
minScore: { $min: "$PlayerDetails.PlayerScore" }
}}
]);
หมายเหตุ
$unwindเพิ่มจำนวนเอกสารชั่วคราว - ระวัง Memory/Performance กับอาร์เรย์ใหญ่- MongoDB 5.0+ มี
$reduceและ$accumulatorสำหรับคำนวณใน $project โดยไม่ต้อง $unwind