【问题标题】:Order of $sort and $limit in mongo db aggregationmongodb聚合中$sort和$limit的顺序
【发布时间】:2022-01-25 18:04:39
【问题描述】:

$skip 和 $limit 的顺序在管道中重要吗?

我使用运行操作管道的 mongoose 聚合。最后加上跳过和限制。

   projectModel.aggregate(pipeline)
  .sort({ updatedAt: -1 })
  .skip(skip)
  .limit(limit)

我的管道看起来像

$match(userId) > $lookup(html_collection) > $lookup(records_collection) > $sort(on updatedAt from mongoose) > $skip(mongoose) > $limit(mongoose)

我在分页期间观察到的是 $limit 受到尊重,但 $skip 仅在管道末端发生。例如:

第 1 页:跳过 = 0,限制 = 10

.explain() 清除 $match 阶段的文档数为 10。

第 2 页:跳过 = 10,限制 = 10

通过$match阶段的文档数为20(跳过+限制),有20个文档进入下一阶段。 $lookup 对 20 个文档进行。减慢我们的流水线,在最后阶段 $skip 丢弃前 10 个文档。在这里,我们浪费了前 10 个文档的工作。

这导致我们的管道出现问题,分页速度变慢。

解决方案:我们最终做的是在 $match 之后移动 $limit 和 $skip。 然后 $limit = 跳过 + 限制,$skip = 跳过。我们认为将文档限制为 limit = skip + limit 将获取文档,而下一阶段的 $skip 将拒绝不必要的文档,从而仅向 $lookup 阶段提供预期的文档。

第 1 页:跳过 = 0,限制 = 10 $limit = 0 + 10 = 10 后跟 $skip = 0

第 2 页:跳过 = 10,限制 = 10 $limit = 10 + 10 后跟 $skip = 10

我们的管道现在看起来像:

$match(userId) > $sort(updatedAt) > $limit(limit + skip) > $skip (skip) > $lookup(html_collection) > $lookup(records_collection)

这是供您参考的样本收集方案:

    PROJECT COLLECTION     
    {
     id: ObjectId,
     records: [ObjectId],
     userId: ObjectId
    }
     
    RECORDS COLLECTION
     
    {
     id: ObjectId,
     text: string
    }
     
    HTML COLLECTION
     
    {
     id: ObjectId,
     html: string,
     projectId: ObjectId
    }

问题:

  1. 这种行为是有意的还是 $skip 和 $limit 有问题?
  2. 我们提出的解决方案是否正确?它会扩展吗?我认为最后一页有太多的文档清除了 $match 阶段,但这也是 MongoDB 内部做对的事情......如我们案例的第 2 页所示?

【问题讨论】:

    标签: mongodb mongoose aggregation-framework


    【解决方案1】:

    是的,您的解决方案是正确的方法:

    • $skip 只忽略管道给它的设定数量
    • $limit 实际上只返回告知的金额。

    所以你所做的链接翻译成这句话:

    我们限制在 20 个,而跳过前 10 个结果将获得第二组 10 个文档。

    如果你说你限制在 10,然后通过跳过忽略 10,你就没有文档了。

    对于您的第二个问题,是的,它会扩展,请继续使用如下格式:

    const baseLimit = 10
    const skip = 10
    const limit = baseLimit + sort
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-07-15
      • 1970-01-01
      • 2015-01-25
      • 2018-05-09
      • 2020-12-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多