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

优化MongoDB聚合查询:筛选近60天下单的客户

MongoDB聚合查询优化:筛选近60天有订单的客户

现有查询的问题分析

你的两个聚合查询效率低下的核心原因是从数据量更大的Customers集合出发做全量关联,且未合理利用索引:

  1. Aggregation 1:先对100万条客户数据全量关联Orders,再过滤时间符合条件的记录,相当于先完成100万次关联操作,再筛掉大部分结果,完全浪费算力。
  2. Aggregation 2:虽然在lookup子管道中加入了时间过滤,但错误地将$project放在$match之前,导致MongoDB无法利用Orders集合的created_at索引(索引需在字段未被裁剪前使用),依然要处理大量无关订单数据。

优化思路:从Orders集合反向关联

Orders集合数据量(16万)远小于Customers(100万),先筛选出近60天的订单,再关联对应客户,能大幅减少关联的数据量。同时调整索引和聚合步骤,最大化利用索引效率。

具体优化方案

1. 优化索引

给Orders集合创建复合索引,让时间筛选和订单ID查询一步完成,无需回表:

db.orders.createIndex({ created_at: 1, id: 1 })

该索引会让第一步的时间过滤直接通过索引完成,同时直接返回订单ID,不需要读取完整的订单文档。

2. 优化后的聚合查询

[
  // 第一步:快速筛选近60天的订单,利用复合索引直接获取订单ID
  {
    $match: {
      created_at: {
        $gt: { $dateSubtract: { startDate: "$$NOW", unit: "day", amount: 60 } }
      }
    }
  },
  // 第二步:只保留订单ID,减少数据传输量
  {
    $project: {
      _id: 0,
      order_id: "$id"
    }
  },
  // 第三步:关联对应的客户数据,利用Customers的order_id索引
  {
    $lookup: {
      from: "customers",
      localField: "order_id",
      foreignField: "order_id",
      as: "customer_info"
    }
  },
  // 展开客户数组(一个订单对应一个客户)
  {
    $unwind: "$customer_info"
  },
  // 第四步:投影需要的客户字段(按需调整)
  {
    $project: {
      _id: "$customer_info._id",
      customer_id: "$customer_info.id",
      name: "$customer_info.name",
      phone: "$customer_info.phone",
      latest_order_time: "$created_at"
    }
  },
  // 可选:去重,保留每个客户的最新订单记录(如果一个客户有多条近60天订单)
  {
    $group: {
      _id: "$_id",
      customer_id: { $first: "$customer_id" },
      name: { $first: "$name" },
      phone: { $first: "$phone" },
      latest_order_time: { $max: "$latest_order_time" }
    }
  }
]

优化点说明

  • 反向聚合顺序:从Orders出发先过滤,只处理近60天的订单(假设占比远低于100%),再关联客户,避免全量客户关联的巨大开销。
  • 索引最大化利用:复合索引让时间筛选和ID获取一步完成,Customers的order_id索引在关联时直接命中。
  • 数据裁剪前置:在聚合早期就用$project裁剪不必要的字段,减少内存占用和数据传输。
  • 动态日期计算:用$dateSubtract结合$$NOW自动计算近60天的日期,无需手动修改查询条件。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 05:05:16