MongoDB Aggregation Pipeline เป็น framework ประมวลผลข้อมูลแบบขั้นตอน (stages) แต่ละ stage แปลง documents และส่งต่อไปยัง stage ถัดไป เหมาะสำหรับ analytics, transformation, joining
สร้างคอลเลกชันและข้อมูลตัวอย่าง
> db.demo218.insertOne({"Name":"Chris","Branch":"CS",Marks:[65,78,36,90]});
{ "acknowledged" : true, "insertedId" : ObjectId("5e3e5f4903d395bdc2134712") }
> db.demo218.insertOne({"Name":"David","Branch":"ME",Marks:[56,45,42,51]});
{ "acknowledged" : true, "insertedId" : ObjectId("5e3e5f6203d395bdc2134713") }
> db.demo218.insertOne({"Name":"Chris","Branch":"CS",Marks:[78,65,89]});
{ "acknowledged" : true, "insertedId" : ObjectId("5e3e5f6c03d395bdc2134714") }
แสดงข้อมูลทั้งหมด
> db.demo218.find();
ผลลัพธ์: 3 เอกสาร Chris 2 records (CS), David 1 record (ME)
Query Aggregation Pipeline: หา CS Students ที่ได้ Marks > 88
> db.demo218.aggregate([
{ "$unwind": "$Marks" },
{ "$match": {
"Branch": "CS",
"Marks": { "$gt": 88 }
}},
{ "$group": {
"_id": "$_id",
"Branch": { "$first": "$Branch" },
"Marks": { "$first": "$Marks" }
}}
])
คำอธิบาย Stages:
$unwind: "$Marks": แยก array Marks → แต่ละคะแนนเป็น document แยก (Chris doc 1 → 4 docs, Chris doc 2 → 3 docs, David → 4 docs)$match: กรองเฉพาะ Branch="CS" และ Marks > 88$group: รวมกลับตาม _id เดิม ใช้ $first เก็บ Branch และ Marks ที่เจอแรก (ซึ่งเป็นคะแนน > 88 เพราะ sort ไม่ได้ระบุ)
ผลลัพธ์
{ "_id" : ObjectId("5e3e5f6c03d395bdc2134714"), "Branch" : "CS", "Marks" : 89 }
{ "_id" : ObjectId("5e3e5f4903d395bdc2134712"), "Branch" : "CS", "Marks" : 90 }
ได้ 2 records: Chris (doc 2) Marks 89, Chris (doc 1) Marks 90
Common Pipeline Stages
| Stage | 목적 | ตัวอย่าง |
|---|---|---|
$match | Filter documents | {$match: {status: "active"}} |
$project | Reshape fields | {$project: {name: 1, _id: 0}} |
$group | Group & aggregate | {$group: {_id: "$dept", avg: {$avg: "$salary"}}} |
$sort | Sort documents | {$sort: {age: -1}} |
$limit | Limit results | {$limit: 10} |
$skip | Skip documents | {$skip: 20} |
$unwind | Deconstruct array | {$unwind: "$tags"} |
$lookup | Join collections | {$lookup: {from: "orders", localField: "_id", foreignField: "userId", as: "orders"}} |
$addFields | Add computed fields | {$addFields: {fullName: {$concat: ["$first", " ", "$last"]}}} |
$facet | Multiple pipelines | {$facet: {cats: [...], dogs: [...]}} |