我尝试使用 mongoose 查询具有唯一列和分页的 mongo 集合。
我有分页数据,我需要知道总唯一计数、偏移量/页码,但查询需要在没有$skip
and 的情况下执行$limit
,这会返回整个集合并占用内存以获取计数。我尝试使用 distinct
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();
};
您的聚合管道基本没问题 - 您应该添加一个
$sort
阶段,以便始终可靠地分页 1、2、3、4。而不是有时是 3、2、1、4,有时是 2、4、1、3。(顺便说一句,您的聚合管道在 `$token_id` 周围有反引号 - 它应该是单引号或双引号,就像我下面做的那样。)通过在组后放置一个
$count
阶段并删除其他所有内容来获取唯一记录总数。将其作为单独的聚合查询执行。用于分页的聚合管道和Mongo Playground:
总计的聚合管道和Mongo Playground:
您可以在一次聚合中同时完成这两项操作,
$unionWith
但我不建议这样做,因为获取结果然后从实际文档中单独提取“总计”项目是一种不必要的复杂化。