เพื่อจัดเรียงข้อมูลภายในอาร์เรย์ซ้อน (nested array) ให้ใช้ $unwind แยกอาร์เรย์ก่อน แล้วค่อย $sort และ $group รวมกลับ
> db.demo505.insertOne({
... "details": [
... { Name: "Chris", "Score": 58 },
... { Name: "Bob", "Score": 45 },
... { Name: "John", "Score": 68 },
... { Name: "David", "Score": 46 }
... ]
... });
{ "acknowledged" : true, "insertedId" : ObjectId("5e882a6b987b6e0e9d18f574") }
แสดงข้อมูลก่อนจัดเรียง:
> db.demo505.find();
{ "_id" : ObjectId("5e882a6b987b6e0e9d18f574"), "details" : [ { "Name" : "Chris", "Score" : 58 }, { "Name" : "Bob", "Score" : 45 }, { "Name" : "John", "Score" : 68 }, { "Name" : "David", "Score" : 46 } ] }
คิวรีจัดเรียงตาม Score จากน้อยไปมาก (Ascending)
> db.demo505.aggregate([
... { $unwind: "$details" },
... { $sort: { "details.Score": 1 } },
... { $group: { _id: "$_id", details: { $push: "$details" } } }
... ]);
ผลลัพธ์ - จัดเรียงจากคะแนนต่ำสุดไปสูงสุด:
{ "_id" : ObjectId("5e882a6b987b6e0e9d18f574"), "details" : [ { "Name" : "Bob", "Score" : 45 }, { "Name" : "David", "Score" : 46 }, { "Name" : "Chris", "Score" : 58 }, { "Name" : "John", "Score" : 68 } ] }
ขั้นตอนการทำงาน
- $unwind: แยกอาร์เรย์ details ให้แต่ละออบเจกต์เป็นเอกสารแยกต่างหาก
- $sort: จัดเรียงตาม details.Score (1 = ascending, -1 = descending)
- $group: รวมกลับเป็นอาร์เรย์เดิมด้วย $push โดยเก็บลำดับที่จัดเรียงแล้ว
วิธีนี้ใช้ได้กับการจัดเรียงข้อมูลย่อยภายในเอกสาร เช่น รายการสั่งซื้อ, คะแนนสอบ, หรือ log ต่างๆ