Natural Order: เรียงตามลำดับจัดเก็บทางกายภาพ
{ $natural: 1 } หรือ { $natural: -1 } เรียงเอกสารตาม **ลำดับที่จัดเก็บบนดิสก์ (physical order)** ซึ่งโดยปกติตรงกับลำดับการ insert (LIFO: Last In First Out)
ตัวอย่างข้อมูล
> db.demo614.insertOne({ "CountryName": "US" });
> db.demo614.insertOne({ "CountryName": "UK" });
> db.demo614.insertOne({ "CountryName": "AUS" });
> db.demo614.insertOne({ "CountryName": "IND" });
คำสั่ง เรียง $natural: -1 (ล่าสุดก่อน)
> db.demo614.find().sort({ $natural: -1 })
ผลลัพธ์
{ "_id": ObjectId("5e988cebf6b89257f5584d91"), "CountryName": "IND" }
{ "_id": ObjectId("5e988ce3f6b89257f5584d90"), "CountryName": "AUS" }
{ "_id": ObjectId("5e988ce0f6b89257f5584d8f"), "CountryName": "UK" }
{ "_id": ObjectId("5e988cddf6b89257f5584d8e"), "CountryName": "US" }
คุณสมบัติของ $natural
- ไม่ต้องใช้ Index - อ่านตามลำดับบนดิสก์โดยตรง
- เร็วสำหรับ full collection scan - ไม่ต้อง sort ในหน่วยความจำ
- ไม่คงที่ (Non-deterministic) - ลำดับอาจเปลี่ยนหลัง update/delete/compact
- Capped Collection - 保證 insertion order (คงที่)
ตัวอย่างการใช้งาน
// หาเอกสาร 10 รายการล่าสุด (ถ้าไม่มี createdAt index)
db.collection.find().sort({ $natural: -1 }).limit(10);
// หาเอกสาร 10 รายการแรก
db.collection.find().sort({ $natural: 1 }).limit(10);
ข้อจำกัด
- ไม่ทำงานกับ Sharded Cluster (ต้องใช้ _id หรือ field อื่น)
- หลังจาก update ขนาดใหญ่กว่าเดิม เอกสารอาจย้ายตำแหน่ง
- หลัง compact/repair ลำดับจะ reset
แนวทางแทนที่ที่ดีกว่า
// ใช้ _id (มี timestamp embedded) - แนะนำ
db.collection.find().sort({ _id: -1 }).limit(10);
// หรือสร้าง createdAt field
db.collection.createIndex({ createdAt: -1 });
db.collection.find().sort({ createdAt: -1 }).limit(10);