การแทรกข้อมูลลง Array ในตำแหน่งที่กำหนด (Specific Index) ใน MongoDB
ใช้ $push operator ร่วมกับ $each และ $position เพื่อแทรก element เข้าไปใน Array ที่ตำแหน่ง (index) ที่ต้องการ
ตัวอย่างการสร้างคอลเลกชันและเพิ่มข้อมูล
> db.insertToSpecificIndexDemo.insertOne({"StudentName":"Larry","StudentSubjects":["MySQL","Java"]});
{ "acknowledged" : true, "insertedId" : ObjectId("5c9d2562a629b87623db1b2c") }
> db.insertToSpecificIndexDemo.insertOne({"StudentName":"Chris","StudentSubjects":["C++","C"]});
{ "acknowledged" : true, "insertedId" : ObjectId("5c9d2573a629b87623db1b2d") }
แสดงข้อมูลก่อนอัปเดต
> db.insertToSpecificIndexDemo.find().pretty();
ผลลัพธ์:
{ "_id" : ObjectId("5c9d2562a629b87623db1b2c"), "StudentName" : "Larry", "StudentSubjects" : [ "MySQL", "Java" ] }
{ "_id" : ObjectId("5c9d2573a629b87623db1b2d"), "StudentName" : "Chris", "StudentSubjects" : [ "C++", "C" ] }
แทรกข้อมูลที่ Index 0 (จุดเริ่มต้น) ของเอกสาร Chris
> db.insertToSpecificIndexDemo.update(
{ _id: ObjectId("5c9d2573a629b87623db1b2d") },
{ $push: {
StudentSubjects: {
$each: [ {"CoreSubject": "MongoDB"} ],
$position: 0
}
}}
);
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
ตรวจสอบผลลัพธ์หลังอัปเดต
> db.insertToSpecificIndexDemo.find().pretty();
ผลลัพธ์ (CoreSubject: MongoDB ถูกแทรกที่ Index 0):
{ "_id" : ObjectId("5c9d2562a629b87623db1b2c"), "StudentName" : "Larry", "StudentSubjects" : [ "MySQL", "Java" ] }
{ "_id" : ObjectId("5c9d2573a629b87623db1b2d"), "StudentName" : "Chris", "StudentSubjects" : [
{ "CoreSubject" : "MongoDB" },
"C++",
"C"
] }
คำอธิบาย Parameters
- $each : ระบุ array ของค่าที่จะเพิ่ม (แม้แค่ค่าเดียวก็ต้องใส่ใน array)
- $position : ตำแหน่งที่จะแทรก (0 = เริ่มต้น, 1 = ตำแหน่งที่ 2, ...)
- ค่าติดลบ: $position: -1 จะแทรกก่อนตัวสุดท้าย, -2 ก่อนตัวสุดท้าย 2 ตัว, เป็นต้น
ตัวอย่างเพิ่มเติม
// แทรกหลายค่าที่ Index 1 (หลัง element แรก)
db.collection.update(
{ _id: ... },
{ $push: {
arrayField: {
$each: ["new1", "new2", "new3"],
$position: 1
}
}}
)
// แทรกที่ตำแหน่งก่อนสุดท้าย
db.collection.update(
{ _id: ... },
{ $push: {
arrayField: {
$each: ["newValue"],
$position: -1
}
}}
)
// แทรกที่ท้าย Array (ปกติ) - ไม่ต้องระบุ $position
db.collection.update(
{ _id: ... },
{ $push: { arrayField: "newValue" } }
)
// หรือหลายค่า
db.collection.update(
{ _id: ... },
{ $push: { arrayField: { $each: ["new1", "new2"] } } }
)
ข้อควรระวัง
- ประสิทธิภาพ: การแทรกกลาง Array ต้อง shift elements ทั้งหมดหลังตำแหน่งนั้น อาจช้าเมื่อ Array ใหญ่
- Atomic: การ update ครั้งเดียวเป็น Atomic operation
- $slice: สามารถรวมกับ $slice เพื่อจำกัดขนาด Array ได้ (เช่น เก็บแค่ 100 รายการล่าสุด)
ตัวอย่างรวม $position, $slice, $sort
db.collection.update(
{ _id: ... },
{ $push: {
scores: {
$each: [ {score: 95, date: new Date()} ],
$position: 0,
$slice: 10, // เก็บแค่ 10 รายการแรก
$sort: { score: -1 } // เรียงจากมากไปน้อย
}
}}
)