具有唯一列和总计数的分页

问题描述 投票:0回答:1

我尝试使用 mongoose 查询具有唯一列和分页的 mongo 集合。

我有分页数据,我需要知道总的唯一计数、偏移量/页码,但需要在没有

$skip
$limit
的情况下执行查询,这会返回整个集合并消耗内存只是为了获取计数。我尝试使用不同的

await Token.find().distinct('token_id').countDocuments().exec()

这没有给出正确的唯一计数。

在 mongo 上工作了一段时间,据我所知,聚合会收集所有记录,然后过滤/分组并将结果发送回来。只要节点应用程序不执行任何内存密集型操作,这对我来说就很好。

那么,如何实现总的唯一记录(如果可能的话,不获取集合,仅获取计数)和分页以正确的方式工作。

下面是猫鼬模型

Token
并按
token_id
分组以获取唯一记录。 (预计可能会有重复
token_id

const getUniqueTokens = async () => {
  return Token.aggregate([{
      $group: {
        _id: `$token_id`,
        // Get the first document for each unique field
        doc: {
          $first: "$$ROOT"
        }
      }
    },
    {
      $replaceRoot: {
        // Replace root to get back the original document structure
        newRoot: "$doc"
      }
    },
    {
      $skip: offset,
    },
    {
      $limit: 100
    }
  ]).exec();
};
mongodb mongoose mongodb-query
1个回答
0
投票

您的聚合管道大部分都很好 - 您应该添加一个

$sort
阶段,以便始终可靠地对 1、2、3、4 进行分页。而不是有时 3、2、1、4 次,其他时候 2、4、1、3 次。

通过在组后面放置

$count
阶段来获取总的唯一记录;并将其作为单独的聚合执行。

聚合管道和Mongo Playground用于分页

db.token.aggregate([
  {
    $group: {
      _id: "$token_id",
      // Get the first document for each unique field
      doc: { $first: "$$ROOT" }
    }
  },
  {
    $replaceRoot: {
      // Replace root to get back the original document structure
      newRoot: "$doc"
    }
  },
  { $sort: { token_id: 1 } },
  { $skip: offset },
  { $limit: 100 }
])

聚合管道和 Mongo Playground 总计

db.token.aggregate([
  {
    $group: {
      _id: "$token_id",
      // Get the first document for each unique field
      doc: {
        $first: "$$ROOT"
      }
    }
  },
  { $count: "total" }
])

可以使用

$unionWith
在一次聚合中完成这两项操作,但我不建议这样做,因为获取结果然后从实际文档中单独提取“总计”项目是一种不必要的复杂化。

© www.soinside.com 2019 - 2024. All rights reserved.