Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> MongoDB

วิธีใช้ $slice Operator ดึง Element สุดท้ายของ Array ใน MongoDB

การใช้ $slice Operator เพื่อดึง Element สุดท้ายของ Array ใน MongoDB

ใช้ $slice ใน Projection ของ find() ด้วยค่าติดลบ เพื่อดึง Element จากท้าย Array กลับมา

ไวยากรณ์

db.yourCollectionName.find({}, {yourArrayFieldName: {$slice: -1}});

ตัวอย่างการสร้างคอลเลกชันและเพิ่มข้อมูล

> db.getLastElementOfArrayDemo.insertOne({"StudentName":"James","StudentMathScore":[78,68,98]});
{ "acknowledged" : true, "insertedId" : ObjectId("5c9d2d71a629b87623db1b2e") }
> db.getLastElementOfArrayDemo.insertOne({"StudentName":"Chris","StudentMathScore":[88,56,34]});
{ "acknowledged" : true, "insertedId" : ObjectId("5c9d2d83a629b87623db1b2f") }
> db.getLastElementOfArrayDemo.insertOne({"StudentName":"Larry","StudentMathScore":[99]});
{ "acknowledged" : true, "insertedId" : ObjectId("5c9d2d8ea629b87623db1b30") }
> db.getLastElementOfArrayDemo.insertOne({"StudentName":"Robert","StudentMathScore":[90,78,67,66,75,73]});
{ "acknowledged" : true, "insertedId" : ObjectId("5c9d2dada629b87623db1b31") }

แสดงข้อมูลทั้งหมด

> db.getLastElementOfArrayDemo.find().pretty();

ผลลัพธ์:

{ "_id" : ObjectId("5c9d2d71a629b87623db1b2e"), "StudentName" : "James", "StudentMathScore" : [ 78, 68, 98 ] }
{ "_id" : ObjectId("5c9d2d83a629b87623db1b2f"), "StudentName" : "Chris", "StudentMathScore" : [ 88, 56, 34 ] }
{ "_id" : ObjectId("5c9d2d8ea629b87623db1b30"), "StudentName" : "Larry", "StudentMathScore" : [ 99 ] }
{ "_id" : ObjectId("5c9d2dada629b87623db1b31"), "StudentName" : "Robert", "StudentMathScore" : [ 90, 78, 67, 66, 75, 73 ] }

ดึง Element สุดท้ายของ Array (StudentMathScore)

> db.getLastElementOfArrayDemo.find({}, {StudentMathScore: {$slice: -1}});

ผลลัพธ์ (เฉพาะ Element สุดท้าย):

{ "_id" : ObjectId("5c9d2d71a629b87623db1b2e"), "StudentName" : "James", "StudentMathScore" : [ 98 ] }
{ "_id" : ObjectId("5c9d2d83a629b87623db1b2f"), "StudentName" : "Chris", "StudentMathScore" : [ 34 ] }
{ "_id" : ObjectId("5c9d2d8ea629b87623db1b30"), "StudentName" : "Larry", "StudentMathScore" : [ 99 ] }
{ "_id" : ObjectId("5c9d2dada629b87623db1b31"), "StudentName" : "Robert", "StudentMathScore" : [ 73 ] }

คำอธิบาย $slice Values

ค่า $sliceความหมายตัวอย่าง Array [1,2,3,4,5]
33 Element แรก (จากหน้า)[1, 2, 3]
-33 Element สุดท้าย (จากท้าย)[3, 4, 5]
[2, 3]Skip 2, Limit 3 (จากหน้า)[3, 4, 5]
[-3, 2]Skip 3 จากท้าย, Limit 2[3, 4]

ตัวอย่าง $slice เพิ่มเติม

// 3 Element แรก
db.collection.find({}, { scores: { $slice: 3 } });

// 3 Element สุดท้าย
db.collection.find({}, { scores: { $slice: -3 } });

// Skip 2, Take 3 (Pagination ใน Array)
db.collection.find({}, { scores: { $slice: [2, 3] } });

// กรณี Array ว่างหรือไม่มี Field -> คืน [] หรือ Missing

การใช้ $slice ใน Aggregation (MongoDB 3.2+)

db.collection.aggregate([
    { $project: {
        lastScore: { $arrayElemAt: ["$scores", -1] },  // ค่า Scalar โดยตรง
        lastThree: { $slice: ["$scores", -3] }         // Array 3 ตัวท้าย
    }}
]);

ความแตกต่าง:

  • find() + $slice: คืน Array (แม้ 1 Element ก็เป็น Array)
  • $arrayElemAt: คืน Scalar Value โดยตรง
  • aggregation $slice: คืน Array

กรณี Array ว่างหรือ Missing Field

> db.demo.insertOne({ name: "Empty", scores: [] });
> db.demo.insertOne({ name: "Missing" }); // ไม่มี scores field

> db.demo.find({}, { scores: { $slice: -1 } });
{ "name": "Empty", "scores": [] }
{ "name": "Missing" }  // ไม่มี scores field ในผลลัพธ์

Best Practices

  • ใช้ $slice: -1 ใน find() สำหรับกรณีง่าย ต้องการ Array กลับมา
  • ใช้ $arrayElemAt: ["$field", -1] ใน Aggregation ต้องการ Scalar Value
  • รวมกับ Projection ฟิลด์อื่นๆ เพื่อลด Bandwidth
  • Index ไช่วย $slice ได้ (ต้อง Scan Document)