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

MongoDB如何实现带分组、内连接和嵌套条件的聚合查询统计符合要求的工人数量

这个需求完全可以通过MongoDB聚合实现,你原有查询的核心问题出在关联逻辑错误、没有提前过滤最新记录、字段路径引用错误三个方面,以下是正确的实现方案:


先明确关联关系链

  • 工人最新位置:WorkerLocationContext → 按worker分组取最新 → 关联LocationSensor拿location → 关联Location过滤非REST区域
  • 最新温度数据:HeatMeasureContext → 按sensor分组取最新 → 关联MeasureSensor拿location和placementType
  • 两者通过location字段关联后按温度阈值过滤

完整聚合查询代码

const limit = 27; // 可根据需求调整温度阈值
WorkerLocationContext.aggregate([
  // 1. 取每个worker的最新位置记录
  { $sort: { createdAt: -1 } },
  { $group: {
    _id: "$worker",
    latestLocation: { $first: "$$ROOT" }
  }},
  { $replaceRoot: { newRoot: "$latestLocation" } },

  // 2. 关联LocationSensor拿到对应location ID
  { $lookup: {
    from: "locationsensors", // 需和你数据库实际集合命名一致,mongoose默认转小写复数
    localField: "sensor",
    foreignField: "_id",
    as: "locationSensor"
  }},
  { $unwind: "$locationSensor" },

  // 3. 关联Location表,过滤休息区的工人
  { $lookup: {
    from: "locations",
    localField: "locationSensor.location",
    foreignField: "_id",
    as: "location"
  }},
  { $unwind: "$location" },
  { $match: { "location.type": { $ne: "REST" } } },

  // 4. 关联匹配对应位置的最新温度数据
  { $lookup: {
    from: "heatmeasurecontexts",
    let: { workerLocationId: "$locationSensor.location" },
    pipeline: [
      // 4.1 取每个温度传感器的最新上报记录
      { $sort: { createdAt: -1 } },
      { $group: {
        _id: "$sensor",
        latestHeat: { $first: "$$ROOT" },
        hmDatetime: { $first: "$createdAt" }
      }},
      { $replaceRoot: { newRoot: "$latestHeat" } },
      // 4.2 关联MeasureSensor拿到位置和安装类型
      { $lookup: {
        from: "measuresensors",
        localField: "sensor",
        foreignField: "_id",
        as: "measureSensor"
      }},
      { $unwind: "$measureSensor" },
      // 4.3 只保留和当前工人位置匹配的温度数据
      { $match: { $expr: { $eq: ["$measureSensor.location", "$$workerLocationId"] } } }
    ],
    as: "heatData"
  }},
  { $unwind: "$heatData" },

  // 5. 按温度阈值过滤符合要求的记录
  { $match: {
    $or: [
      { $and: [
        { "heatData.measureSensor.placementType": "INTERNAL" },
        { "heatData.internal": { $gte: limit } }
      ]},
      { $and: [
        { "heatData.measureSensor.placementType": "EXTERNAL" },
        { "heatData.external": { $gte: limit } }
      ]}
    ]
  }},

  // 6. 统计最终符合条件的工人总数,同时返回最新数据时间
  { $group: {
    _id: null,
    workerCount: { $count: {} },
    latestHeatTime: { $max: "$heatData.hmDatetime" },
    latestLocationTime: { $max: "$createdAt" }
  }}
])

关键逻辑说明

  1. 所有上下文表取最新记录都采用先按创建时间倒排,再分组取第一条的逻辑,保证只处理最新的位置和温度数据
  2. 多层关联均先join对应关联表再取值,避免了直接引用不存在的嵌套字段的错误
  3. 嵌套lookup中使用$expr实现动态关联匹配,保证工人位置和温度数据的location严格对应
  4. 提前过滤休息区工人,减少后续关联的计算量

按你提供的样本数据,阈值设为27时,最终统计符合条件的工人数量为2,和样本中2个位于Location2的工人对应。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 16:57:04