MongoDB’s pipeline aggregation is – like most things in application development these days – confusing as hell (let’s be honest). Writing database queries using JavaScript’s object literal syntax is frightening, and quite frankly ridiculous. But here we are using it anyway, so we might as well know how to do one of the most useful database operations out there: a query across a collection that returns us a COUNT of the total results and a PORTION of the total results. Discovering how to do this in Mongo was crucial for us so that we could get ag-grid‘s virtual pagination to play nice! Now we can share the wisdom to the world in this blog post so that 1) others don’t pull their hair out figuring this out and 2) we don’t forget it.

So here’s a quick run down of how you can lookup (populate in mongoose vernacular), match (aka filter), sort, count, and limit using Mongo’s aggregation pipeline. And…. breathe.

Heads up: function calls in this example are to mongoose.

/**
* Query blog posts by user -> paginated results and a total count.
* @param userId {ObjectId} ID of user to retrieve blog posts for
* @param startRow {Number} First row to return in results
* @param endRow {Number} Last row to return in results
* @param [filter] {Object} Optional extra matching query object
* @param [sort] {Object} Optional sort query object
* @returns {Object} Object -> `{ rows, count }`
*/
function queryBlogPostsByUser (userId, startRow, endRow, filter = {}, sort = false) {
if (!(user instanceof mongoose.Types.ObjectId)) {
throw new Error('userId must be ObjectId')
} else if (typeof startRow !== 'number') {
throw new Error('startRow must be number')
} else if (typeof endRow !== 'number') {
throw new Error('endRow must be number')
} const query = [
// more lookups go here if you need them
// we have a many-to-one from blogPost -> user
{ $lookup: {
from: 'users',
localField: 'user',
foreignField: '_id',
as: 'user'
} },
// each blog has a single user (author) so flatten it using $unwind
{ $unwind: '$user' },
// filter the results by our userId
{ $match: Object.assign({ 'user._id': userId }, filter) }
] if (sort) {
// maybe we want to sort by blog title or something
query.push({ $sort: sort })
} query.push(
{ $group: {
_id: null,
// get a count of every result that matches until now
count: { $sum: 1 },
// keep our results for the next operation
results: { $push: '$$ROOT' }
} },
// and finally trim the results to within the range given by start/endRow
{ $project: {
count: 1,
rows: { $slice: ['$results', startRow, endRow] }
} }
) return BlogPost
.aggregate(query)
.then(([{ count, rows }]) => ({ count, rows }))
}

来源: https://outlandish.com/blog/tutorial/pagination-using-mongo-lookup-match-sort-count-and-limit-with-the-aggregation-pipeline/

使用Mongo进行分页的更多相关文章

  1. CentOS7.5安装MongoDB4.0与CRUD基本操作

    一 MongoDB简介 MongoDB 是一个基于分布式文件存储的数据库.由 C++ 语言编写.旨在为 WEB 应用提供可扩展的高性能数据存储解决方案. MongoDB 是一个介于关系数据库和非关系数 ...

  2. 解决mongodb查询慢的问题

    最近项目上一直在用mongodb作为数据库,mongodb有他的优势,文档型类json格式存储数据,修改起来比传统的关系型数据库更方便,但是最近在用mongodb出现了查询缓慢的问题,我用命令行查询, ...

  3. mongo中的分页查询

    /** * @param $uid * @param $app_id * @param $start_time * @param $end_time * @param $start_page * @p ...

  4. mongo数据排序和分页显示

    数据排序 使用sort()1 升序-1 降序自然排序 数据插入的顺序$natural db.stu.drop(); db.stu.insert({,,"address":" ...

  5. MongoDB 分页查询的方法及性能

    最近有点忙,本来有好多东西可以总结,Redis系列其实还应该有四.五.六...不过<Redis in Action>还没读完,等读完再来总结,不然太水,对不起读者. 自从上次Redis之后 ...

  6. Lind.DDD.Repositories.Mongo层介绍

    回到目录 之前已经发生了 大叔之前讲过被仓储化了的Mongodb,而在大叔开发了Lind.DDD之后,决定把这个东西再搬到本框架的仓储层来,这也是大势所趋的,毕竟mongodb是最像关系数据库的NoS ...

  7. MongoDB学习笔记~为IMongoRepository接口添加分页取集合的方法

    回到目录 对于数据分页,我们已经见的太多了,几乎每个列表页面都要用到分页,这已经成了一种定理了,在进行大数据展示时,如果不去分页,而直接把数据加载到内存,这简直是不可以去相向的,呵呵,在很多ORM工具 ...

  8. [MongoDB]Mongo基本使用:

    汇总: 1. [MongoDB]安装MongoDB2. [MongoDB]Mongo基本使用:3. [MongoDB]MongoDB的优缺点及与关系型数据库的比较4. [MongoDB]MongoDB ...

  9. mongo基本操作

    创建数据库文件的存放位置,比如d:/mongodb/data/db.启动mongodb服务之前需要必须创建数据库文件的存放文件夹,否则命令不会自动创建,而且不能启动成功. 打开cmd(windows键 ...

随机推荐

  1. tensorflow 基本内容

    tensorflow的结构 1.使用图(graphs)来表示计算任务 2.在被称之为会话(Session)的上下文(context)中执行图 3.使用tensor表示数据 4.通过变量(Variabl ...

  2. webpack(5) -开发环境

    使用 source map (仅用于开发环境) 当 webpack 打包源代码时,可能会很难追踪到 error(错误) 和 warning(警告) 在源代码中的原始位置.例如,如果将三个源文件(a.j ...

  3. python类与对象-如何为创建大量实例节省内存

    如何为创建大量实例节省内存 问题举例 在网络游戏中,定义玩家类Player(id, name, level...), 每个玩家在线将创建一个Player实例,当在线人数很多时,将产生大量实例, 如何降 ...

  4. tensorflow(4)踩过的一些坑

    版本问题 1.1 版本的一个BUG ValueError: Variable rnn/basic_lstm_cell/weights already exists, disallowed. 结合这个文 ...

  5. Oracle函数中对于NO_DATA_FOUND异常处理的研究

    一直以来有一个困惑,一直没解决,昨天一哥们问我这个问题,决心弄清楚,终于得到了答案.先看下面这个函数: create or replace function fn_test(c_xm varchar) ...

  6. 18.12.09-C语言练习:兔子繁衍问题 / Fibonacci 数列

    题目: 问题解析: 这是典型的/Fibonacci 数列问题.具体这里不赘述. 问题中不论是初始的第1对兔子还是以后出生的小兔子都是从第3个月龄起每个月各生一对兔子. 设n1,n2,n3分别是每个月1 ...

  7. 使用cocos creator的过程中碰到的问题记录

    1>编辑器不能识别脚本里面@property类型,显示为null,脚本拖不上去 是@property的类循环引用导致的,可以改变组件类型到cc.Node解决 2> Cannot read ...

  8. 2018 CCPC网络赛 几道数学题

    1002 Congruence equation 题目链接  : http://acm.hdu.edu.cn/showproblem.php?pid=6439 题解 : https://www.zyb ...

  9. P3974 [TJOI2015]组合数学

    题目描述 为了提高智商,ZJY开始学习组合数学.某一天她解决了这样一个问题:给一个网格图,其中某些格子有财宝.每次从左上角出发,只能往右或下走.问至少要走几次才可能把财宝全捡完. 但是她还不知足,想到 ...

  10. 网络-05-端口号-F5-负载均衡设-linux端口详解大全--TCP注册端口号大全备

    [root@test1:Standby] config # [root@test1:Standby] config # [root@test1:Standby] config # [root@test ...