MongoDB查找 - >匹配 - >小组花太多时间

发布于 2025-01-18 23:44:23 字数 914 浏览 0 评论 0原文

我已经部署了一个生产应用程序,并且每天都会生成大量数据。但是此查询通常需要大约15秒钟才能完成。这是不好的。我想要很快。如何重写此查询以进行优化以及这里出了什么问题?

        const activity_data = await Activity.aggregate([
            {
                $lookup: {
                    from: 'tokens',
                    localField: 'n_id',
                    foreignField: 'token_id',
                    as: 'sale_status'
                },
            },
            {
                $match: {
                    activity_type: 'FOR_SALE',
                    'sale_status.for_sale': true,
                }
            },
            {
                $group: {
                    _id: '$n_id',
                    createdAt: { $max: '$createdAt' },
                },
            },
            {
                $sort: { createdAt: -1 }
            },
            {
                $limit: 15
            }
        ]);

I have a production app deployed and it generates a good amount of data every day. But this query usually takes around 15 seconds to complete. This is not okay. I want it way quickly. How do I rewrite this query for optimization and what went wrong here?

        const activity_data = await Activity.aggregate([
            {
                $lookup: {
                    from: 'tokens',
                    localField: 'n_id',
                    foreignField: 'token_id',
                    as: 'sale_status'
                },
            },
            {
                $match: {
                    activity_type: 'FOR_SALE',
                    'sale_status.for_sale': true,
                }
            },
            {
                $group: {
                    _id: '$n_id',
                    createdAt: { $max: '$createdAt' },
                },
            },
            {
                $sort: { createdAt: -1 }
            },
            {
                $limit: 15
            }
        ]);

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

逆光下的微笑 2025-01-25 23:44:24

简要查看您的查询,您可以进行一些小调整以最大程度地减少中间结果。

db.collection.aggregate([
  {
    "$match": {
      activity_type: "FOR_SALE"
    }
  },
  {
    $lookup: {
      from: "tokens",
      let: {
        n: "$n_id"
      },
      pipeline: [
        {
          "$match": {
            $expr: {
              $and: [
                {
                  $eq: [
                    "$n",
                    "$token_id"
                  ]
                },
                {
                  $eq: [
                    "$for_sale",
                    true
                  ]
                }
              ]
            }
          }
        }
      ],
      as: "sale_status"
    },
    
  },
  {
    $match: {
      "sale_status.for_sale": true
    }
  },
  {
    $group: {
      _id: "$n_id",
      createdAt: {
        $max: "$createdAt"
      }
    }
  },
  {
    $sort: {
      createdAt: -1
    }
  },
  {
    $limit: 15
  }
])

您可以看到activity_type过滤器已移至早期阶段。 for_sale过滤器还将过滤器移至子围栏中,以最大程度地减少查找结果。

如果给出更多的查询上下文,可能会有更多的事情要做。说$ lookup如果将for_sale字段划定到活动集合是一个选项,则可以跳过。

From a brief look at your query, you can do some minor tweaks to minimize the intermediate result.

db.collection.aggregate([
  {
    "$match": {
      activity_type: "FOR_SALE"
    }
  },
  {
    $lookup: {
      from: "tokens",
      let: {
        n: "$n_id"
      },
      pipeline: [
        {
          "$match": {
            $expr: {
              $and: [
                {
                  $eq: [
                    "$n",
                    "$token_id"
                  ]
                },
                {
                  $eq: [
                    "$for_sale",
                    true
                  ]
                }
              ]
            }
          }
        }
      ],
      as: "sale_status"
    },
    
  },
  {
    $match: {
      "sale_status.for_sale": true
    }
  },
  {
    $group: {
      _id: "$n_id",
      createdAt: {
        $max: "$createdAt"
      }
    }
  },
  {
    $sort: {
      createdAt: -1
    }
  },
  {
    $limit: 15
  }
])

You can see the activity_type filter is moved to earlier stage. The for_sale filter is also moved into a sub-pipeline to minimize lookup results.

There are potentially more things to do if more context on your query is given. Say the $lookup could have been skipped if denormalizing the for_sale field into the Activity collection is an option.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文