ใช้ Aggregation Pipeline ด้วย $group และ $sum เพื่อคำนวณผลรวมของฟิลด์ที่อยู่ลึกใน Sub-document (Nested Field)
สร้างคอลเลกชันและข้อมูลตัวอย่าง
> db.summingSubDocumentDemo.insertOne({_id: 101, "CustomerDetails": {"CustomerPurchase": {"CustomerPurchaseAmount": 2000}}});
{ "acknowledged": true, "insertedId": 101 }
> db.summingSubDocumentDemo.insertOne({_id: 102, "CustomerDetails": {"CustomerPurchase": {"CustomerPurchaseAmount": 3000}}});
{ "acknowledged": true, "insertedId": 102 }
> db.summingSubDocumentDemo.insertOne({_id: 103, "CustomerDetails": {"CustomerPurchase": {"CustomerPurchaseAmount": 5000}}});
{ "acknowledged": true, "insertedId": 103 }
แสดงข้อมูลทั้งหมด
> db.summingSubDocumentDemo.find().pretty();
ผลลัพธ์: 3 เอกสาร มี Amount 2000, 3000, 5000
Aggregation: Sum ฟิลด์ลึก (Dot Notation ใน Path)
> db.summingSubDocumentDemo.aggregate([
{$group: {
_id: "",
totalAmount: {$sum: "$CustomerDetails.CustomerPurchase.CustomerPurchaseAmount"}
}},
{$project: {_id: 0, totalAmount: 1}}
]);
ผลลัพธ์: ผลรวม = 10000
{"totalAmount": 10000}
การทำงาน
$groupจัดกลุ่มทั้งหมด (_id: "") → กลุ่มเดียว$sumสะสมค่าจาก PathCustomerDetails.CustomerPurchase.CustomerPurchaseAmount$projectซ่อน _id แสดงแค่ totalAmount
ตัวอย่างขยาย: Group ตาม Category แล้ว Sum
// สมมติมี Category ใน Document
db.summingSubDocumentDemo.aggregate([
{$group: {
_id: "$CustomerDetails.CustomerPurchase.Category",
totalAmount: {$sum: "$CustomerDetails.CustomerPurchase.CustomerPurchaseAmount"},
count: {$sum: 1}
}},
{$sort: {totalAmount: -1}}
]);
Operator คำนวณอื่นๆ ใน $group
| Operator | คำอธิบาย |
|---|---|
$sum | ผลรวม (Numeric) |
$avg | ค่าเฉลี่ย |
$min | ค่าต่ำสุด |
$max | ค่าสูงสุด |
$first | ค่าแรกในกลุ่ม (ต้อง $sort ก่อน) |
$last | ค่าสุดท้ายในกลุ่ม |
$push | สร้าง Array รวมค่าทั้งหมด |
$addToSet | สร้าง Array ค่า Unique |
$stdDevPop | Standard Deviation (Population) |
$stdDevSamp | Standard Deviation (Sample) |