Để sắp xếp kết quả truy vấn trong MongoDB, bạn sử dụng phương thức sort() trên cursor.
Cú pháp cơ bản
Sắp xếp tăng dần (Ascending)
db.collection.find().sort({ fieldName: 1 })
Sắp xếp giảm dần (Descending)
db.collection.find().sort({ fieldName: -1 })
1= Ascending (tăng dần: 1, 2, 3... / A, B, C...)-1= Descending (giảm dần: 3, 2, 1... / C, B, A...)
Ví dụ minh họa
Tạo collection và dữ liệu
> db.sortingDemo.insertOne({"Value":100});
{ "acknowledged" : true, "insertedId" : ObjectId("5c8f8e2ed3c9d04998abf006") }
> db.sortingDemo.insertOne({"Value":1});
{ "acknowledged" : true, "insertedId" : ObjectId("5c8f8e31d3c9d04998abf007") }
> db.sortingDemo.insertOne({"Value":150});
{ "acknowledged" : true, "insertedId" : ObjectId("5c8f8e34d3c9d04998abf008") }
> db.sortingDemo.insertOne({"Value":250});
{ "acknowledged" : true, "insertedId" : ObjectId("5c8f8e37d3c9d04998abf009") }
> db.sortingDemo.insertOne({"Value":5});
{ "acknowledged" : true, "insertedId" : ObjectId("5c8f8e3bd3c9d04998abf00a") }
> db.sortingDemo.insertOne({"Value":199});
{ "acknowledged" : true, "insertedId" : ObjectId("5c8f8e3ed3c9d04998abf00b") }
> db.sortingDemo.insertOne({"Value":243});
{ "acknowledged" : true, "insertedId" : ObjectId("5c8f8e44d3c9d04998abf00c") }
> db.sortingDemo.insertOne({"Value":290});
{ "acknowledged" : true, "insertedId" : ObjectId("5c8f8e48d3c9d04998abf00d") }
Xem dữ liệu gốc (không sort)
> db.sortingDemo.find().pretty();
{"_id" : ObjectId("5c8f8e2ed3c9d04998abf006"), "Value" : 100}
{"_id" : ObjectId("5c8f8e31d3c9d04998abf007"), "Value" : 1}
{"_id" : ObjectId("5c8f8e34d3c9d04998abf008"), "Value" : 150}
{"_id" : ObjectId("5c8f8e37d3c9d04998abf009"), "Value" : 250}
{"_id" : ObjectId("5c8f8e3bd3c9d04998abf00a"), "Value" : 5}
{"_id" : ObjectId("5c8f8e3ed3c9d04998abf00b"), "Value" : 199}
{"_id" : ObjectId("5c8f8e44d3c9d04998abf00c"), "Value" : 243}
{"_id" : ObjectId("5c8f8e48d3c9d04998abf00d"), "Value" : 290}
Trường hợp 1: Sắp xếp tăng dần (Ascending)
> db.sortingDemo.find().sort({Value:1});
{"_id" : ObjectId("5c8f8e31d3c9d04998abf007"), "Value" : 1}
{"_id" : ObjectId("5c8f8e3bd3c9d04998abf00a"), "Value" : 5}
{"_id" : ObjectId("5c8f8e2ed3c9d04998abf006"), "Value" : 100}
{"_id" : ObjectId("5c8f8e34d3c9d04998abf008"), "Value" : 150}
{"_id" : ObjectId("5c8f8e3ed3c9d04998abf00b"), "Value" : 199}
{"_id" : ObjectId("5c8f8e44d3c9d04998abf00c"), "Value" : 243}
{"_id" : ObjectId("5c8f8e37d3c9d04998abf009"), "Value" : 250}
{"_id" : ObjectId("5c8f8e48d3c9d04998abf00d"), "Value" : 290}
Trường hợp 2: Sắp xếp giảm dần (Descending)
> db.sortingDemo.find().sort({Value:-1});
{"_id" : ObjectId("5c8f8e48d3c9d04998abf00d"), "Value" : 290}
{"_id" : ObjectId("5c8f8e37d3c9d04998abf009"), "Value" : 250}
{"_id" : ObjectId("5c8f8e44d3c9d04998abf00c"), "Value" : 243}
{"_id" : ObjectId("5c8f8e3ed3c9d04998abf00b"), "Value" : 199}
{"_id" : ObjectId("5c8f8e34d3c9d04998abf008"), "Value" : 150}
{"_id" : ObjectId("5c8f8e2ed3c9d04998abf006"), "Value" : 100}
{"_id" : ObjectId("5c8f8e3bd3c9d04998abf00a"), "Value" : 5}
{"_id" : ObjectId("5c8f8e31d3c9d04998abf007"), "Value" : 1}
Sắp xếp đa trường (Compound Sort)
db.collection.aggregate([
{ $match: { status: "active" } },
{ $sort: { createdAt: -1 } },
{ $limit: 10 }
])
Hiệu năng và Index
| Trường hợp | Hiệu năng | Giải pháp |
|---|---|---|
| Sort có index phù hợp | Nhanh (index scan) | Tạo index match sort pattern |
| Sort không index | Chậm (in-memory sort) | Giới hạn 32MB RAM, dùng allowDiskUse |
| Sort + limit nhỏ | Tối ưu (top-k algorithm) | MongoDB tự tối ưu |
Best Practice
- Luôn tạo index cho trường thường sort:
db.coll.createIndex({field: 1})hoặc-1 - Compound index: thứ tự trường trong index phải match thứ tự trong sort
- Dùng
hint()để force index nếu optimizer chọn sai - Tránh sort trên trường không index với collection lớn
Lưu ý về null và missing field
- Giá trị
nullvà trường không tồn tại được coi là nhỏ nhất (xuất hiện đầu khi sort ascending) - Dùng
{$exists: true}trong query để loại bỏ nếu cần