mongoose MongoDB返回错误的行,包含$sort、$skip和$limit

doinxwow  于 2022-11-24  发布在  Go
关注(0)|答案(2)|浏览(180)

这是我正在使用的函数

MyModel.aggregate([
  { $match: query },
  { $sort: { 'createdAt': -1 } },
  { $skip: skip },
  { $limit: 10 }
  ], { allowDiskUse : true });

query用于过滤行。skip是基于分页的动态值(即0、10、20...)。问题是,每页的行都不正确。例如,我可以同时在第1、2、3、4页看到特定的行!一些行也丢失了。
为什么会这样?

sxissh06

sxissh061#

我认为这个问题的关键是你在这篇评论中分享的信息:
许多行的createdAt具有相同的值。$sort是否有可能无法正常工作?
这并不是说排序不一定“正常工作”,而是它没有足够的信息来确定性地排序。123的值本身不会出现在另一个123的值之前或之后。正如@诺埃尔所指出的,您需要为排序提供一个或多个附加字段。
以下文档中也包含此内容:
MongoDB不会以特定的顺序将文档存储在集合中。当对包含重复值的字段进行排序时,包含这些值的文档可能会以任何顺序返回。
如果需要一致的排序顺序,请在排序中至少包含一个包含唯一值的字段。保证这一点的最简单方法是在排序查询中包含_id字段。
这是因为_id字段是唯一的。如果您采用这种方法,则会将排序更改为:

{ $sort: { 'createdAt': -1, _id: 1 } },
1l5u6lss

1l5u6lss2#

limit应使用基于分页(即0、10、20 ...)的动态值,则skip应为(page - 1 * limit)
比方说,

const limit = 10;
const page = 1;
const skip = (page - 1) * limit; // basically is 0

MyModel.aggregate([
  { $match: query },
  { $sort: { 'createdAt': -1 } },
  { $skip: skip },
  { $limit: limit }
  ], { allowDiskUse : true });

因此您的查询将跳过0个数据,并从第一个结果开始,直到第10个
因此如果您页面查询为2,

const limit = 10;
const page = 2;
const skip = (page - 1) * limit; // basically is 10

MyModel.aggregate([
  { $match: query },
  { $sort: { 'createdAt': -1 } },
  { $skip: skip },
  { $limit: limit }
  ], { allowDiskUse : true });

因此您的查询将跳过10个数据,并从第11个结果开始,一直到第20个

相关问题