ใช้ $zip ใน aggregation pipeline เพื่อ transpose (สลับแถว-คอลัมน์) อาร์เรย์หลายตัวให้กลายเป็นอาร์เรย์ของออบเจ็กต์ สร้างคอลเลกชันตัวอย่าง:
> db.demo339.insertOne({Id:101,Score1:["98","56"],Score2:[67,89]});
{ "acknowledged" : true, "insertedId" : ObjectId("5e529ee5f8647eb59e5620a2") }
แสดงข้อมูล:
> db.demo339.find();
คิวรีใช้ $zip รวม Score1 และ Score2:
> db.demo339.aggregate([
{
"$project": {
"AllArrayObject": {
"$map": {
"input": {
"$objectToArray": {
"$arrayToObject": {
"$zip": {
"inputs": [ "$Score1", "$Score2" ]
}
}
}
},
"as": "el",
"in": {
"Score1": "$$el.k",
"Score2": "$$el.v"
}
}
}
}
}
])
ผลลัพธ์:
{ "_id" : ObjectId("5e529ee5f8647eb59e5620a2"), "AllArrayObject" : [ { "Score1" : "98", "Score2" : 67 }, { "Score1" : "56", "Score2" : 89 } ] }
คำอธิบาย $zip
$zipรวมอาร์เรย์หลายตัวโดยจับคู่ตาม index (index 0 กับ index 0, index 1 กับ index 1, ...)- อาร์เรย์ที่สั้นกว่าจะถูกตัดทิ้ง (truncate to shortest)
- รูปแบบ output:
[[val1_arr1, val1_arr2], [val2_arr1, val2_arr2], ...] - ตัวอย่างใช้
$arrayToObject->$objectToArray->$mapเพื่อแปลงเป็น array of objects ที่มี key/value ชัดเจน
รูปแบบง่ายกว่า (MongoDB 4.4+)
ใช้ $map โดยตรงกับ $zip:
{ $project: { zipped: { $map: { input: { $zip: { inputs: ["$Score1", "$Score2"] } }, in: { Score1: "$$this.0", Score2: "$$this.1" } } } } }