ESR = Equality, Sort, Range — thứ tự field trong compound index nên là: field so sánh bằng trước, rồi field dùng để sort, cuối cùng là field so sánh khoảng ($gt, $lt, $in dạng dải).
// query: status bằng, sort theo createdAt, lọc amount theo khoảng
db.orders.find({ status: 'paid', amount: { $gte: 100000 } }).sort({ createdAt: -1 })
db.orders.createIndex({ status: 1, createdAt: -1, amount: 1 }) // E - S - RLý do: index là cấu trúc có thứ tự. Field equality thu hẹp về một dải liên tục; trong dải đó các entry đã sắp sẵn theo field kế tiếp nên sort đọc thẳng không cần sắp lại. Nếu đặt field range trước field sort, dải kết quả không còn thứ tự theo createdAt → MongoDB phải gom hết vào bộ nhớ rồi sắp.
Đó cũng là nguyên nhân lỗi quen thuộc:
Sort exceeded memory limit of 33554432 bytes, but did not opt in to external sortingSort trong bộ nhớ bị giới hạn 32MB cho query thường (stage $sort trong aggregation giới hạn 100MB).
Cách sửa đúng là thêm index phủ được sort theo ESR, không phải nâng giới hạn hay bật allowDiskUse.