ใช้ Aggregation Pipeline ทำ Slice ซ้อน Slice (Multi-level Array Slicing)
MongoDB ไม่มี Slice Chain ตรงตัว แต่สามารถทำได้ด้วย $unwind หลายรอบ แล้ว $group + $last/$first หรือใช้ $arrayElemAt (4.4+)
ตัวอย่างข้อมูล: อาร์เรย์ 2 มิติ
> db.sliceOfSliceDemo.insertOne({
"Name": "John",
"Details": [ ["First 1:1", "First 1:2"], ["second 2:1", "Second 2:2"] ]
});
Pipeline: ดึงค่า "Second 2:2" (Index [1][1])
> db.sliceOfSliceDemo.aggregate([
{ $match: { "Name": "John" } },
{ $unwind: "$Details" }, // แบนชั้น 1: ได้ 2 เอกสารย่อย
{ $unwind: "$Details" }, // แบนชั้น 2: ได้ 4 เอกสารย่อย
{ $group: { "_id": "$Name", "Details": { $last: "$Details" } } }, // เอาตัวสุดท้าย
{ $project: { "Name": "$_id", "Details": 1 } }
]);
ผลลัพธ์
{ "_id" : "John", "Details" : "Second 2:2", "Name" : "John" }
วิธีทันสมัยกว่า (MongoDB 4.4+): ใช้ $arrayElemAt
db.sliceOfSliceDemo.aggregate([
{ $match: { "Name": "John" } },
{ $project: {
Name: 1,
// Details[1][1] = เอา Sub-array index 1 แล้วเอา Element index 1
value: { $arrayElemAt: [ { $arrayElemAt: ["$Details", 1] }, 1 ] }
}}
]);
ผลลัพธ์
{ "_id" : ObjectId("..."), "Name" : "John", "value" : "Second 2:2" }
ฟังก์ชัน Array ใหม่ๆ (MongoDB 4.4+)
| Operator | คำอธิบาย |
|---|---|
$arrayElemAt | ดึง Element ที่ Index ระบุ (รองรับ Negative Index) |
$slice | ตัด Sub-array (เริ่มต้น, จำนวน) |
$first / $last | Element แรก/สุดท้าย (ใน $group หรือ $project) |
$reduce | Reduce Array เป็นค่าเดียว (Custom Logic) |
$map | Transform ทุก Element ใน Array |
$filter | กรอง Element ใน Array |
สรุป
- เก่า: $unwind × N → $group → $last/$first (ซับซ้อน ช้า)
- ใหม่ (4.4+):
$arrayElemAtซ้อนกัน หรือ$slice- เร็ว อ่านง่าย ไม่ต้อง Unwind - Slice Chain = การเข้าถึง Multi-dimensional Array โดย Index