Mongo 聚合:查找后的排序阶段和展开速度太慢

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

我有一个包含大约 30 个属性的集合,其中 2 个属性是与其他 2 个集合的关系 (ObjectId)。我需要能够按 2 个子集合的列对父集合进行排序。

为此,我编写了一个如下所示的管道:

 Document.aggregate([
  {
    $match: {
      deleted: false,
    },
  },
  {
    $lookup:
    {
      from: 'companies',
      localField: 'company',
      foreignField: '_id',
      as: 'company',
    },
  },
  {
    $unwind:
    {
      path: '$company',
      preserveNullAndEmptyArrays: true,
    },
  },
  {
    $lookup:
    {
      from: 'suppliers',
      localField: 'supplier',
      foreignField: '_id',
      as: 'supplier',
    },
  },
  {
    $unwind:
    {
      path: '$supplier',
      preserveNullAndEmptyArrays: true,
    },
  },
  {
    $sort: { 'company.name': -1 },
  },
  {
    $skip: 0,
  },
  {
    $limit: 10,
  }
]);

问题是这太慢了。在 Compass 中,它超出了时间限制,当我在节点中运行它时,大约需要 10 秒才能处理。父集合的大小约为 60k。如果没有排序阶段,它的运行时间约为 25 毫秒。另外,当我将排序阶段移动到管道顶部时,它运行得非常快,但如果我想按“company.name”属性排序,结果不正确。父集合中的“company”和“supplier”属性均已编入索引。

我读过,为了让排序阶段使用索引,需要将其与“匹配”阶段一起放在管道的开头,但这并不能满足我按属性排序的要求子集合。不可能在 100 毫秒内完成这个运行吗?我错过了什么?

编辑1

解释如下:

{ stages:
   [ { '$cursor':
        { query: { state: true },
          queryPlanner:
           { plannerVersion: 1,
             namespace: 'test.documents',
             indexFilterSet: false,
             parsedQuery: { state: { '$eq': true } },
             winningPlan:
              { stage: 'FETCH',
                inputStage:
                 { stage: 'IXSCAN',
                   keyPattern: { state: 1 },
                   indexName: 'state_1',
                   isMultiKey: false,
                   multiKeyPaths: { state: [] },
                   isUnique: false,
                   isSparse: false,
                   isPartial: false,
                   indexVersion: 2,
                   direction: 'forward',
                   indexBounds: { state: [ '[true, true]' ] } } },
             rejectedPlans: [] } } },
     { '$lookup':
        { from: 'companies',
          as: 'company',
          localField: 'company',
          foreignField: '_id',
          unwinding: { preserveNullAndEmptyArrays: true } } },
     { '$lookup':
        { from: 'suppliers',
          as: 'supplier',
          localField: 'supplier',
          foreignField: '_id',
          unwinding: { preserveNullAndEmptyArrays: true } } },
     { '$sort': { sortKey: { 'company.name': -1 }, limit: 10 } } ],
  ok: 1 }

文档集合中,

company
supplier
state
字段都是索引。

mongodb mongodb-query aggregation-framework
1个回答
0
投票

我最近遇到了类似的超时问题,我在这种情况下所做的并且对我有用的是将查找对象投影为这样: 就像我们的案例中的 company.name 一样: @project: { 名称 = $company.name } 现在对此名称属性进行排序,它不会显示错误。这很奇怪,即使它应该直接作用于查找对象,但这仍然对我有用。

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