MongoDB sắp xếp kết quả truy vấn với sort và phân trang với limit và skip — được nối trên một find cursor. Kết hợp lại, chúng xử lý việc sắp xếp và trả về các trang dữ liệu, thiết yếu để hiển thị kết quả.
MongoDB sắp xếp kết quả truy vấn với sort và phân trang với limit và skip — được nối trên một find cursor. Kết hợp lại, chúng xử lý việc sắp xếp và trả về các trang dữ liệu, thiết yếu để hiển thị kết quả.
db.users.find().sort({ age: 1 }); // tăng dần theo age (1 = tăng)
db.users.find().sort({ age: -1 }); // giảm dần (-1 = giảm)
db.users.find().sort({ country: 1, name: 1 }); // theo country, rồi name (phá hòa)
db.users.find().sort({ createdAt: -1 }); // mới nhất trước (phổ biến)
sort nhận một document field:hướng (1 tăng, -1 giảm). Nhiều field cung cấp việc phá hòa.
db.users.find().sort({ name: 1 }).limit(10); // 10 đầu tiên (trang 1)
db.users.find().sort({ name: 1 }).skip(10).limit(10); // bỏ 10, lấy 10 (trang 2)
// trang N: .skip((N-1) * pageSize).limit(pageSize)
limit(n) trả về tối đa n document; skip(m) bỏ qua m document đầu. Kết hợp lại chúng triển khai phân trang theo offset (trang N qua skip + limit).
// ❌ phân trang không sort → thứ tự không nhất quán (các trang có thể trùng/bỏ sót)
db.users.find().skip(10).limit(10);
// ✅ sort theo một field ổn định để các trang nhất quán
db.users.find().sort({ _id: 1 }).skip(10).limit(10);
Không có sort, thứ tự document không được đảm bảo, nên các trang phân trang có thể không nhất quán. Luôn sort theo một field ổn định (như _id) khi phân trang.
// ⚠️ skip(1000000) phải quét/bỏ qua một triệu doc → chậm ở các trang sâu
// ✅ phân trang theo range (cursor) — hiệu quả hơn nhiều cho tập dữ liệu lớn
db.users.find({ _id: { $gt: lastSeenId } }).sort({ _id: 1 }).limit(10);
// → dùng _id của document cuối để lấy trang tiếp (dùng index, không bỏ qua)
Sắp xếp trên một field ĐƯỢC ĐÁNH INDEX là hiệu quả. Sắp xếp một tập kết quả lớn KHÔNG có index
yêu cầu sắp xếp trong bộ nhớ (giới hạn kích thước — có thể thất bại/chậm với sort lớn).
→ Đánh index các field bạn sắp xếp theo.
Sắp xếp và phân trang là nền tảng để hiển thị dữ liệu hữu ích trong MongoDB — sắp xếp kết quả và trả về các trang quản lý được là nhu cầu gần như phổ quát (bất kỳ danh sách, feed, hay bảng nào trong ứng dụng), nên hiểu chúng là kiến thức thiết yếu hằng ngày.
Biết sort (sắp xếp theo field với 1/-1, với phá hòa) và limit/skip (cho phân trang theo offset — trả về các trang dữ liệu) bao quát các nhu cầu phổ biến để trình bày kết quả truy vấn.
Hai điểm thực tế đặc biệt quan trọng: luôn sort khi phân trang (không có nó, thứ tự document không được đảm bảo, gây ra các trang không nhất quán bị trùng hoặc bỏ sót document — một bug thực sự, cùng vấn đề như trong SQL), và hiểu rằng skip chậm ở các trang sâu (nó phải quét và bỏ qua tất cả document trước đó) — nên phân trang theo range (cursor) (dùng _id cuối cùng đã thấy để lấy trang tiếp, tận dụng index mà không bỏ qua) hiệu quả hơn nhiều cho tập dữ liệu lớn, một kỹ thuật hiệu năng giá trị.
Biết rằng sắp xếp trên field được đánh index là hiệu quả trong khi sort lớn không đánh index có thể chậm hoặc thất bại (giới hạn sort trong bộ nhớ) cũng là quan trọng — đánh index các field bạn sort theo.
Vì sắp xếp và phân trang cần thiết cho hầu hết mọi việc hiển thị dữ liệu, và vì yêu cầu nhất quán (sort để phân trang ổn định) và các cân nhắc hiệu năng (skip vs phân trang theo range, sort được đánh index) ảnh hưởng trực tiếp đến tính đúng đắn và tốc độ, nên hiểu sắp xếp và phân trang của MongoDB — sort, phân trang offset với skip/limit, yêu cầu sort ổn định, lựa chọn thay thế theo range hiệu quả, và đánh index các field sort — là kiến thức thiết yếu, thường xuyên áp dụng để xây dựng ứng dụng trình bày dữ liệu MongoDB một cách hiệu quả và có hiệu năng tốt.