$ lookup汇总中的性能问题

时间:2019-04-25 14:40:53

标签: mongodb

以下mongodb查询对我有用:

db.customers.aggregate([
      {
        $lookup:
        {
          from: 'orders',
          localField: 'orders',
          foreignField: '_id',
          as: 'orders_docs'
        }
      },
      {
        $unwind: "$orders_docs"
      },
      {
        $lookup:
        {
          from: 'products',
          localField: 'orders_docs._id',
          foreignField: 'orders',
          as: 'products_docs'
        }
      },
      {
        $match:
        {
          'products_docs._id': mongoose.Types.ObjectId(req.params.product_id)
        }
      }
    ])

有了它,我找到了特定产品(req.params.product_id)的买家。

我的模式为:Products hasMany OrdersCustomers hasMany Orders

当我增加记录数量时,我的问题就来了:例如,有10万个订单(这似乎仍然很低),1万个客户和1万个产品,请求似乎没有结束。

我的3个收藏集上没有任何特定的索引,但是我只使用_id(自然是索引)来进行请求,不是吗?

因此,我的问题是:如何改善此请求的性能?

1 个答案:

答案 0 :(得分:1)

查找不使用索引,因此导致此汇总完全扫描所有3个集合, 由于您要查找特定的产品ID,因此我建议您从产品集合“开始”聚合。

db.products.aggregate([
      {
        $match:
        {
          '_id': mongoose.Types.ObjectId(req.params.product_id)
        }
      },
      {
        $lookup:
        {
          from: 'orders',
          localField: 'orders',
          foreignField: '_id',
          as: 'orders_docs'
        }
      },
      {
        $unwind: "$orders_docs"
      },
      {
        $lookup:
        {
          from: 'users',
          localField: 'orders_docs._id',
          foreignField: 'orders',
          as: 'users'
        }
      },
    ])

这将“希望”使查询小得多,假设所有订单中都没有产品。

还可以考虑添加项目阶段以删除多余的字段,如果您有这么大的字段,这可能会非常有用。

如果运行时仍然是一个问题,请考虑重新构造数据以包含要查找的较小映射对象。