mongo分页查询,同时返回分页记录和记录数
今天做了一个mongo的分页查询,记录一下mongo如何同时返回分页记录和记录数的方法,利用的是mongo的聚合查询里面的$facet阶段,具体使用参考官方文档即可https://docs.mongodb.com/manual/reference/operator/aggregation/facet/
按照官方文档的说法,
Input documents are passed to the
$facet
stage only once.$facet
enables various aggregations on the same set of input documents, without needing to retrieve the input documents multiple times.
利用的是同一个上个阶段返回的记录集,所以从原理上来说是没有二次查询的,效率自然比传统数据库里面的分页实现方式效率上要高,不过由于aggregate的返回只能是文档,所以对于结果的处理可能会比较繁琐,需要自己一个个解析以及类型强转。
类似的facet阶段可以采用如下形式
{ '$facet': { 'count': [ { '$count': 'count' } ], 'data': [ { '$sort': { '_id': 1 } }, { '$skip': 1 }, { '$limit': 2 } ] } }
出来的结果是一个文档,而且由于mongo的单文档限制是16M,所以相应的data字段里面的记录集不能太多,不过既然做分页了,这个地方应该就不需要考虑了吧.出来的记过类似这个样子
{
"count": [
{
"count": 14453
}
],
"data": [
{
"ts": "2021-01-21 08:00:28",
"x": "0.0000",
"y": "0.2089"
},
{
"ts": "2021-01-21 08:01:19",
"x": "0.0000",
"y": "0.3256"
}
]
}
最后如果是在java里面的话,最后的结果集可能就需要自己进行额外处理了,类似这个样子
Object count = ((Document)((List)rs.get(0).get("count")).get(0)).get("count"); Object data = (List)rs.get(0).get("data");
有点不好看.
##补充
如果是在mongo shell 里面的话,对于db.test.find()方法返回的游标cursor,官方文档里面提供了cursor.count(applySkipLimit),用以忽略skip()和limit()的影响,如果applySkipLimit设置为true的话,就会对相关返回结果应用limit和skip的效应,有兴趣的可以自己去研究一下.不知道其他语言的驱动里面有没有相关的api,在java里面我是没找到。