ใช้ $map ใน $project เพื่อแปลงอาร์เรย์ออบเจกต์เป็นอาร์เรย์ค่า
ตัวดำเนินการ $map ใน Aggregation Pipeline ใช้สำหรับแปลงอาร์เรย์หนึ่งรูปแบบเป็นอีกอาร์เรย์หนึ่ง โดยนำแต่ละองค์ประกอบผ่าน expression ที่กำหนด
ตัวอย่างข้อมูลทดสอบ
> db.demo411.insertOne({
"Information": [
{ "Name1": "Chris", "Name2": "David" },
{ "Name1": "John", "Name2": "John" }
]
});
แสดงข้อมูล
> db.demo411.find();
ผลลัพธ์:
{ "_id": ObjectId("..."), "Information": [{ "Name1": "Chris", "Name2": "David" }, { "Name1": "John", "Name2": "John" }] }
คำสั่ง Aggregation ดึงเฉพาะค่า Name1, Name2 เป็นอาร์เรย์ย่อย
> db.demo411.aggregate([
{
$project: {
_id: 0,
Information: {
$map: {
input: "$Information",
as: "out",
in: ["$$out.Name1", "$$out.Name2"]
}
}
}
}
]);
ผลลัพธ์ที่ได้
{ "Information": [["Chris", "David"], ["John", "John"]] }
คำอธิบาย
- input: "$Information": อาร์เรย์ต้นทาง
- as: "out": ตัวแปรอ้างอิงองค์ประกอบปัจจุบัน
- in: ["$$out.Name1", "$$out.Name2"]: สร้างอาร์เรย์ใหม่จากค่าทั้งสองฟิลด์
- ผลลัพธ์เป็นอาร์เรย์ของอาร์เรย์:
[[val1, val2], [val3, val4]]
การใช้งาน $map อื่นๆ
// แปลงเป็นอาร์เรย์สตริงเดียว (concat)
in: { $concat: ["$$out.Name1", " - ", "$$out.Name2"] }
// ผลลัพธ์: ["Chris - David", "John - John"]
// สร้างออบเจกต์ใหม่
in: { fullName: { $concat: ["$$out.Name1", " ", "$$out.Name2"] } }
// ผลลัพธ์: [{fullName: "Chris David"}, {fullName: "John John"}]
ประโยชน์
- Transform ข้อมูลในระหว่าง Query ไม่ต้องดึงมาประมวลผลฝั่ง Application
- ลด Bandwidth และ Memory ใช้งาน
- รองรับ Expression ทั้งหมดของ Aggregation ($concat, $toUpper, $cond, ฯลฯ)