求Mongodb分页的最佳实现

求Mongodb分页的最佳实现

表结构及数据

idnameage
1a3
2a3
3a2
39a2
40a1
41a1
4b3
6b3
5b1
47c2
48c2
21c1

需求

在满足:先按name生序, 再按age降序的前提下. 分页查询, 每页2条数据.

特别说明

18年项目, 已有数据约1400w左右. 因为skip性能低, 在不使用skip的情况下, 是否有其他方案实现分页.

创建一个为你这个查询服务的复合索引就可以啦!分页只能用skip和limit啦

db.col.createIndex({"name":1,"age":-1})

这是2种思路参考

思路1、使用skip()和limit()命令的分页操作。skip(n)命令告诉MongoDB跳过n条结果,limit(n)命令告诉MongoDB限制结果长度为“n”个结果。
代码示例如下:
//Page 1
db.users.find().limit (10)
//Page 2
db.users.find().skip(10).limit(10)
//Page 3
db.users.find().skip(20).limit(10)
........
通常获取第n页的代码像这样:
db.users.find().skip(pagesize*(n-1)).limit(pagesize)
思路2、使用find()和limit()命令的分页操作。通过时间戳或文档中的id以自然顺序存储数据,在文档中的“_id”是一个MongoDB的ObjectID结构,是一个12字节的结构,包含时间戳、机器、进程ID、计数器等。整体想法如下:
1. 获取当前页最后文档的_id
2. 获取大于该“_id”的下一页的文档
代码示例如下:
//Page 1
db.users.find().limit(pageSize);
//Find the id of the last document in this page
last_id = ...
//Page 2
users = db.users.find({'_id'> last_id}). limit(10);
//Update the last id with the id of the last document in this page
last_id = ...

这种做法是使用空间换时间,一般数据库查询的时间大多花在跟数据库的连接上,放在缓存中,可以大大加快查询的速度
users = db.users.find({'_id'> last_id}). sort(..).limit(10);
//Update the last id with the id of the last document in this page
last_id = ...

参考一下

MongoDB实现分页(两种方法) - huhuhuo - 博客园 1.插入实验数据偷懒用下samus,100条。1 for (int i = 0; i < 100; i++)2 {3 Document doc = new Document();4 ... https://www.cnblogs.com/linhan/p/4248679.html#:~:text=MongoDB%E5%AE%9E%E7%8E%B0%E5%88%86%E9%A1%B5%EF%BC%88%E4%B8%A4%E7%A7%8D%E6%96%B9%E6%B3%95%EF%BC%89%201%201.%E6%8F%92%E5%85%A5%E5%AE%9E%E9%AA%8C%E6%95%B0%E6%8D%AE%20%E5%81%B7%E6%87%92%E7%94%A8%E4%B8%8Bsamus%EF%BC%8C100%E6%9D%A1%E3%80%82%201%20for%20%28%20int,%28%29%E4%B8%8Elimit%20%28%29%E6%96%B9%E6%B3%95%20%E5%A6%82%E4%B8%8B%E5%9B%BE%EF%BC%8C%20...%203%203.%E4%B8%A4%E7%A7%8D%E6%96%B9%E6%B3%95%E7%9A%84%E6%AF%94%E8%BE%83%20%E6%96%B9%E6%B3%95%E4%B8%80%E6%AF%94%E8%BE%83%E7%AE%80%E5%8D%95%EF%BC%8C%E4%BD%86skip%E6%96%B9%E6%B3%95%E6%95%88%E7%8E%87%E8%BE%83%E4%BD%8E%EF%BC%8C%E5%9C%A8%E6%95%B0%E6%8D%AE%E9%87%8F%E8%BE%83%E5%A4%9A%E7%9A%84%E6%83%85%E5%86%B5%E4%B8%8B%E6%9B%B4%E6%8E%A8%E8%8D%90%E4%BD%BF%E7%94%A8%E6%96%B9%E6%B3%95%E4%BA%8C%EF%BC%8C%E4%BD%86%E5%8F%AF%E8%83%BD%E4%BC%9A%E5%8D%A0%E7%94%A8%E8%BE%83%E5%A4%9A%E7%9A%84%E5%86%85%E5%AD%98%E7%A9%BA%E9%97%B4%E3%80%82%20

MongoDB分页查询_小胖谢的博客-CSDN博客_mongodb 分页查询 目录前言传统分页思路正确的分页办法降序升序一共多少条ObjectId的有序性问题如果我一定要跳页排序和性能多字段排序用索引优化排序索引Java代码分页抽取分页代码为公共工具类使用工具类把工具类共享到maven仓库参考前言传统关系数据库中都提供了基于row number的分页功能,切换MongoDB后,想要实现分页,则需要修改一下思路。传统分页思路假... https://blog.csdn.net/xieyiweneven/article/details/103164492

img

所以只通过name和age创建符合索引我觉得不可行

补充说明一下.
实际列和值肯定不是这个, 以上表是根据实际情况我手写的一个例子
实际需求是根据分组名升序,再根据日期降序,再根据业绩金额降序.
集合中的_id, created_at, seri_number等字段, 对于数据本身来说,肯定是升序的.
但在采用了以上的排序需求后, 结果集中就没有某一列字段是升序/降序的了.

我也知道需求很傻X, 但是, 公司的需求没办法, 不能修改界面样式, 但还要优化查询速度.
我实在想不出来有什么不使用skip的方案才来提问的.

参考 https://www.jb51.net/article/115496.htm