为了账号安全,请及时绑定邮箱和手机立即绑定

如何在 MongoDB 中对聚合查询结果进行分页并获取总文档数?

如何在 MongoDB 中对聚合查询结果进行分页并获取总文档数?

侃侃无极 2023-04-27 17:24:16
我想通过 $limit 和 $skip 对我的查询结果进行分页,并获得通过查询的文档总数。我现在对结果进行分页是这样的:  const startIndex = (page - 1) * limit  const endIndex = page * limit  const resultObject = {}  resultObject.totalCount = await model.countDocuments(query).exec()  if (endIndex < results.totalCount)    resultObject.next = {page: page + 1, limit}  if (startIndex > 0)    results.prev = {page: page - 1, limit}  resultObject.results = await query.limit(limit).skip(startIndex).exec()这会产生 2 个问题:我执行查询两次(你甚至可以在 1 中执行此操作吗?)出于某种原因,当我的查询是一个聚合时,countDocuments即使在我执行时返回 0,query.exec()我也会得到正确的结果(> 0)所以我的问题是如何在获取文档计数的同时对结果进行分页,就像我现在只使用 1 个查询(并使其与聚合查询一起使用)这样我就可以构建我的resultObject
查看完整描述

1 回答

?
小怪兽爱吃肉

TA贡献1852条经验 获得超1个赞

我找到了一种方法来获取查询的结果,并在同一次“旅行”中对数据库进行计数(仍然是 2 个查询,但在数据库中,因此速度要快得多)


关键是使用$facet(mongodb 3.4+):


const pipeline = [

  {YOUR_QUERY},

  {

    $facet: {

      paginatedResults: [{$skip: startIndex}, {$limit: limit}],

      totalCount: [{$count: 'count'}]

    }

  },

  {

    $addFields: {

      total: {

        $ifNull: [{ $arrayElemAt: ['$totalCount.count', 0]}, 0]

      }

    }

  },

  {

    $project: {

      paginatedResults: 1,

      total: 1

    }

  }

]

解释:$facet在同一个输入(我们的查询结果)上执行多个管道,我们可以有 1 个管道用于对结果进行分页,1 个用于计算总数。


由于$count返回一个包含该count字段的对象,并且 facet 包装在一个数组中,因此$addFields管道将实际count值提取为一个total字段。然后我只是用来$project删除不再需要的totalCount,这就是结果:


  {

     paginatedResults: [RESULTS],

     total: 34

  }


查看完整回答
反对 回复 2023-04-27
  • 1 回答
  • 0 关注
  • 225 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信