分页需先查总数再计算总页数,然后用 skip((pageIndex-1)*pageSize) 和 limit(pageSize) 获取数据,且必须返回 hasMore 字段供前端判断是否还有更多。

直接用 skip + limit 就能实现分页,但必须配合总数统计和边界判断,否则前端会误判“还有更多”或漏数据。
云函数里怎么写分页逻辑
核心是三步:查总数 → 算总页数 → 跳过前 N 条再取 M 条。别只做 skip/limit,否则前端无法知道是否到底。
-
db.collection(...).where(filter).count()必须先执行,total是后续分页判断的依据 -
skip((pageIndex - 1) * pageSize)中pageIndex从 1 开始,不是 0;传 0 或负数会导致跳过异常多条 - 返回结果里务必带上
hasMore: pageIndex ,前端靠这个控制加载状态 - 如果
filter是空对象{},MongoDB 仍会走全表扫描,大数据量时记得加索引(比如按时间字段)
前端调用时怎么传参才不翻车
常见错误是把 pageIndex 写成 0、或没重置页码导致重复请求第一页。
- 首次加载设
pageIndex = 1,后续上拉触底时递增:this.pageIndex++ - 每次调用
uniCloud.callFunction前,检查hasMore === true,否则直接 return -
data字段必须包含dbName、filter、pageIndex、pageSize四个键,缺一个云函数就可能报Cannot read property 'xxx' of undefined - 模糊查询要用
db.command.or+new RegExp(keyword, 'i'),不能直接在filter里写字符串匹配
为什么 skip/limit 在大数据量下变慢
skip 不是“跳到第 N 条”,而是“逐条跳过前 N 条”,当 pageIndex 很大(比如第 1000 页),性能会断崖式下降。
- 10 万条数据查第 1000 页(
pageSize=10)≈ 跳过 9990 条,数据库仍要扫描前 9990 条文档 - 替代方案是用游标分页(cursor-based pagination):记录上一页最后一条的
_id或时间戳,下一页用.where({ _id: db.command.gt(lastId) })查询 - 游标方式无法跳转任意页,但上拉加载场景完全够用,且响应稳定
- 如果必须支持跳页,至少给
where条件字段建索引,否则count()本身也会超时
真正容易被忽略的是:云函数里 count() 和 get() 是两个独立请求,中间如果有并发写入,total 和实际查出的数据条数可能不一致——这不是 bug,是最终一致性模型下的正常现象。


















