id | name | age |
---|---|---|
1 | a | 3 |
2 | a | 3 |
3 | a | 2 |
39 | a | 2 |
40 | a | 1 |
41 | a | 1 |
4 | b | 3 |
6 | b | 3 |
5 | b | 1 |
47 | c | 2 |
48 | c | 2 |
21 | c | 1 |
在满足:先按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 = ...
所以只通过name和age创建符合索引我觉得不可行
补充说明一下.
实际列和值肯定不是这个, 以上表是根据实际情况我手写的一个例子
实际需求是根据分组名升序,再根据日期降序,再根据业绩金额降序.
集合中的_id, created_at, seri_number等字段, 对于数据本身来说,肯定是升序的.
但在采用了以上的排序需求后, 结果集中就没有某一列字段是升序/降序的了.
我也知道需求很傻X, 但是, 公司的需求没办法, 不能修改界面样式, 但还要优化查询速度.
我实在想不出来有什么不使用skip的方案才来提问的.