You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何优化MongoDB聚合查询?附查询代码及索引添加疑问

MongoDB聚合查询优化方案

一、索引优化(必做)

针对你的查询场景,给两个集合创建针对性索引,直接提升关联和过滤的效率:

  1. search_history集合:创建复合索引,覆盖关联字段和时间过滤字段
db.search_history.createIndex({ search_id: 1, created_at: 1 })

这个索引能让MongoDB快速过滤created_at符合条件的记录,同时加速与positive集合的关联匹配,避免全表扫描。

  1. positive集合:给关联字段创建单字段索引
db.positive.createIndex({ search_id: 1 })

用于加速$lookup时的search_id匹配,减少集合扫描的开销。

二、查询逻辑优化(推荐)

原查询从positive出发关联search_history,若positive数据量较大,会触发大量关联查询。建议反转查询顺序,先从search_history过滤聚合,再关联positive,大幅减少处理的数据集:

const tags = await mongo
  .collection("search_history")
  .aggregate<{ word: string; count: number }>([
    // 第一步:先过滤时间范围,缩小初始数据集
    {
      $match: {
        created_at: { $gt: prevSunday.toISOString() },
      },
    },
    // 第二步:按search_id和url去重,避免同一url重复统计
    {
      $group: {
        _id: { search_id: "$search_id", url: "$url" },
      },
    },
    // 第三步:关联positive集合,获取对应的word字段
    {
      $lookup: {
        from: "positive",
        localField: "_id.search_id",
        foreignField: "search_id",
        as: "positive",
        // 只返回需要的word字段,减少数据传输量
        pipeline: [{ $project: { word: 1, _id: 0 } }],
      },
    },
    // 过滤掉未匹配到positive的无效记录
    { $match: { positive: { $ne: [] } } },
    // 展开positive数组(假设一个search_id对应一个positive文档)
    { $unwind: "$positive" },
    // 按word分组,统计去重后的url数量
    {
      $group: {
        _id: "$positive.word",
        count: { $sum: 1 },
      },
    },
    // 重命名字段为目标格式
    {
      $project: {
        _id: 0,
        word: "$_id",
        count: 1,
      },
    },
    // 排序取前50
    { $sort: { count: -1 } },
    { $limit: 50 },
  ])
  .toArray();

优化逻辑说明:

  • 先过滤search_history的时间范围,直接减少后续处理的数据量;
  • 提前对search_id+url去重,避免后续重复统计;
  • 去掉原查询中复杂的$reduce+$concatArrays操作,直接通过$sum统计数量,逻辑更简洁高效;
  • 关联时只返回需要的word字段,减少数据传输开销。

内容的提问来源于stack exchange,提问作者chovy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 02:41:04