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. PySe-007-解决“Chrome正在受到自动软件的控制”

    python使用selenium启动chrome的代码如下所示: #!/usr/local/bin/python # -*- coding: utf-8 -*- from selenium impor ...

  2. eclipse安装使用fat打jar包

    在线安装步骤: eclipse菜单栏 help >software updates >Search for new features to install>new update si ...

  3. Android 跨进程数据共享

    Android 开发过程中,基于功能隔离.进程安全.进程保活等等考虑,我们经常需要为应用划分进程,然后不得不面临跨进程通信和跨进程共享数据的挑战. 跨进程通信 相对来说,跨进程通信比较简单,常用的方式 ...

  4. FEX(Fabric Extender)

    一.FEX Cisco Nexus 2000 FEX作为N5K.N6K.N7K.FI的一个远程线卡,单独的2K是没有网管功能的,必须配合父系交换机使用. 主要解决TOR和EOR的问题,TOR,接线简单 ...

  5. 学号20175313 《实现Linux下cp XXX1 XXX2的功能(二)》第九周

    目录 MyCP2 一.题目要求 二.题目理解 三.需求分析 四.设计思路 五.伪代码分析 六.代码链接 七.代码实现过程中遇到的问题 八.运行结果截图 九.心得体会 十.参考资料 MyCP2 一.题目 ...

  6. ReLU激活函数的缺点

    训练的时候很”脆弱”,很容易就”die”了,训练过程该函数不适应较大梯度输入,因为在参数更新以后,ReLU的神经元不会再有激活的功能,导致梯度永远都是零. 例如,一个非常大的梯度流过一个 ReLU 神 ...

  7. java支付宝接口开发

    在线支付接入支付宝,首先需要去官网申请开发者账号,具体步骤如下: 一.打开官网 1.直接打开链接https://open.alipay.com/platform/home.htm进入 2.百度搜索蚂蚁 ...

  8. 使用JavaScript实现单向链表

    一.实现功能 1.链表元素头部插入 this.unShift = function(data) {} 2.链表元素尾部插入 this.append= function(data) {} //返回boo ...

  9. Fiddler抓包【4】_重定向AutoResponder

    1. 文件及图片替换(Enable rules) 目的:允许从本地返回文件,代替服务器响应,而不用将文件发布到服务器[可用正式环境验证本地文件] 步骤一:抓页面http://ir.baidu.com/ ...

  10. c#中可变参数params关键字学习

    引用 https://www.cnblogs.com/maowp/p/8134342.html 基础知识 1.概念 params 是C#开发语言中关键字, params主要的用处是在给函数传参数的时候 ...