MongoDB 排序与分页
MongoDB 排序与分页查询 · 难度:入门 · +10XP
MongoDB 排序与分页查询
在处理数据库查询结果时,排序和分页是最常用的操作。MongoDB使用sort()方法对查询结果排序,用limit()和skip()方法实现数据分页。这些方法常配合使用,是构建REST API和后台管理系统的核心技能。
sort() 排序
sort()方法接收一个文档对象作为参数,键为字段名,值为1(升序)或-1(降序)。
// 连接数据库
use school
// 基本排序:按年龄升序
db.students.find().sort({ age: 1 })
// 按年龄降序(从大到小)
db.students.find().sort({ age: -1 })
// 多重排序:先按城市升序,城市相同则按成绩降序
db.students.find().sort({ city: 1, score: -1 })
// 按姓名字符串排序(字典序)
db.students.find().sort({ name: 1 })
// 排序 + 条件查询
db.students.find({ score: { $gte: 60 } }).sort({ score: -1 })
// 先筛选及格学生,再按成绩降序
排序规则说明
| 值 | 含义 | 数字排序 | 字符串排序 |
|---|---|---|---|
1 | 升序(ASC) | 从小到大 | A→Z(字典序) |
-1 | 降序(DESC) | 从大到小 | Z→A(反字典序) |
注意:排序字段如果没有创建索引,对大集合排序可能导致性能问题。建议在常用排序字段上创建索引。
limit() 限制返回数量
// 只返回前5条结果
db.students.find().limit(5)
// 查询成绩最高的3名学生
db.students.find().sort({ score: -1 }).limit(3)
// 查询最新创建的10条记录
db.articles.find().sort({ createdAt: -1 }).limit(10)
// limit(0) 等于不加限制,返回全部匹配文档
skip() 跳过文档
// 跳过前5条,返回后面的
db.students.find().skip(5)
// skip + limit 配合实现分页
// 第1页:跳过0条,取10条
db.students.find().skip(0).limit(10)
// 第2页:跳过10条,取10条
db.students.find().skip(10).limit(10)
// 第N页通用公式:skip((page-1) * pageSize).limit(pageSize)
let page = 3;
let pageSize = 10;
db.students.find().skip((page - 1) * pageSize).limit(pageSize);
完整的查询链
这些方法可以链式调用,构建强大的查询语句:
// 查询指定城市及格学生,按成绩降序,取前5名
db.students
.find({ city: "南宁", score: { $gte: 60 } })
.sort({ score: -1 })
.limit(5)
// 分页查询通用封装
function getPage(collection, query, page, pageSize, sortBy) {
return db[collection]
.find(query)
.sort(sortBy)
.skip((page - 1) * pageSize)
.limit(pageSize)
.toArray();
}
// 使用示例:查products集合第2页,每页20条
getPage("products", { category: "电子" }, 2, 20, { price: 1 });
注意事项
1. 方法调用顺序影响结果(但sort/skip/limit三者顺序对结果无影响,MongoDB会自动优化)
2. skip值过大会导致性能问题(可考虑游标分页替代)
3. 排序字段最好有索引(对大集合尤其重要)
4. find()返回游标(Cursor),需遍历或用toArray()获取结果
5. 在mongo shell中默认自动迭代前20条
实战练习
- 查询学生集合,按成绩降序排列并只取前10条
- 实现分页查询:每页15条,分别查询第1页和第3页的数据
- 排序+筛选组合:查询年龄>=18岁的学生,按城市升序、年龄降序
- 用 skip 和 limit 实现简单的"更多"加载功能