Hiểu $natural order trong MongoDB
{ $natural: 1 } (hoặc -1) sắp xếp theo thứ tự tự nhiên lưu trữ trên disk (gần giống LIFO - Last In First Out cho $natural: -1).
1. Dữ liệu insert lần lượt: US, UK, AUS, IND
> db.demo614.insertOne({ CountryName: "US" });
> db.demo614.insertOne({ CountryName: "UK" });
> db.demo614.insertOne({ CountryName: "AUS" });
> db.demo614.insertOne({ CountryName: "IND" });
2. Mặc định find() (không sort) → theo $natural: 1 (FIFO - cũ trước)
> db.demo614.find();
{ "_id": ObjectId("5e988cddf6b89257f5584d8e"), "CountryName": "US" }
{ "_id": ObjectId("5e988ce0f6b89257f5584d8f"), "CountryName": "UK" }
{ "_id": ObjectId("5e988ce3f6b89257f5584d90"), "CountryName": "AUS" }
{ "_id": ObjectId("5e988cebf6b89257f5584d91"), "CountryName": "IND" }
3. Sort $natural: -1 (mới nhất trước - LIFO)
> 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" }
Đặc điểm $natural order
- Phụ thuộc vào storage engine (WiredTiger: gần như insert order)
- Không đảm bảo chính xác 100% thứ tự insert (do update, move chunk, compression...)
- Không dùng index → full collection scan
- Hữu ích: Lấy document mới nhất khi KHÔNG có timestamp/_id sortable
So sánh với _id sort
| Đặc điểm | $natural: -1 | { _id: -1 } |
|---|---|---|
| Dựa trên | Vị trí vật lý trên disk | ObjectId timestamp (4 byte đầu) |
| Độ tin cậy | Thấp (có thể sai sau update) | Cao (ObjectId monotonic) |
| Hiệu suất | Full scan (COllSCAN) | Có thể dùng index _id |
| Cập nhật doc | Có thể thay đổi vị trí | _id không đổi |
Khi nào dùng $natural
- Collection không có _id (hiếm)
- Debug: Xem thứ tự lưu trữ vật lý
- Recovery: Đọc document theo thứ tự disk
- Collection nhỏ, ad-hoc query
Best Practice: Luôn dùng _id hoặc createdAt
// Tốt nhất: Tự thêm createdAt
db.collection.insertOne({ ..., createdAt: new Date() });
// Query mới nhất
db.collection.find().sort({ createdAt: -1 }).limit(10);
// Hoặc dùng _id (có timestamp embedded)
db.collection.find().sort({ _id: -1 }).limit(10);
Tóm lại: $natural là implementation detail, không phải contract. Đừng phụ thuộc vào nó cho logic nghiệp vụ.