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

MongoDB按时间范围匹配后计算value与time的最值及平均值实现

MongoDB 数组筛选+多维度统计聚合实现方案

首先明确:$match 是用来过滤整个文档的操作符,筛选数组内的指定元素需要使用 $filter 操作符实现,完整聚合方案如下:

前置示例结构说明

输入文档结构

{
  "_id": ObjectId("xxx"),
  "data": {
    "time_start": ISODate("2024-01-01T00:00:00Z"),
    "time_end": ISODate("2024-01-03T00:00:00Z")
  },
  "time_values": [
    {"time": ISODate("2023-12-31T12:00:00Z"), "value": 10},
    {"time": ISODate("2024-01-01T12:00:00Z"), "value": 20},
    {"time": ISODate("2024-01-02T12:00:00Z"), "value": 30},
    {"time": ISODate("2024-01-04T12:00:00Z"), "value": 40}
  ]
}

完整聚合管道代码

db.collection.aggregate([
  // 第一步:筛选符合时间范围的数组元素,生成remaining_time_values字段
  {
    $addFields: {
      remaining_time_values: {
        $filter: {
          input: "$time_values",
          cond: {
            $and: [
              {$gte: ["$$this.time", "$data.time_start"]},
              {$lte: ["$$this.time", "$data.time_end"]}
            ]
          }
        }
      }
    }
  },
  // 第二步:计算统计值并写入data字段
  {
    $addFields: {
      data: {
        // 保留原有data字段的内容
        $mergeObjects: [
          "$data",
          // 新增统计字段
          {
            // 计算value平均值
            value_avg: {$avg: "$remaining_time_values.value"},
            // 计算time平均值(时间会转为毫秒数计算后再转回日期格式)
            time_avg: {$toDate: {$avg: {$map: {input: "$remaining_time_values", in: {$toLong: "$$this.time"}}}}},
            // 最小value值
            value_min: {$min: "$remaining_time_values.value"},
            // 最小value对应的time
            time_min: {
              $getField: {
                input: {$minN: {input: "$remaining_time_values", n: 1, sortBy: {value: 1}}},
                field: "time"
              }
            },
            // 最大value值
            value_max: {$max: "$remaining_time_values.value"},
            // 最大value对应的time
            time_max: {
              $getField: {
                input: {$maxN: {input: "$remaining_time_values", n: 1, sortBy: {value: 1}}},
                field: "time"
              }
            }
          }
        ]
      }
    }
  }
  // 可选:如果需要删除原time_values字段,加下面的$project阶段
  // {$project: {time_values: 0}}
])

低版本MongoDB兼容方案

如果你使用的MongoDB版本低于5.2(不支持$minN/$maxN),可以用$reduce实现极值对应的时间查询,以time_min为例:

time_min: {
  $reduce: {
    input: "$remaining_time_values",
    initialValue: null,
    in: {
      $cond: [
        // 初始值为空直接取当前元素的时间
        {$eq: ["$$value", null]},
        "$$this.time",
        // 当前元素value更小则替换时间
        {$cond: [{$lt: ["$$this.value", "$$value.value"]}, "$$this.time", "$$value"]}
      ]
    }
  }
}

输出结构示例

{
  "_id": ObjectId("xxx"),
  "data": {
    "time_start": ISODate("2024-01-01T00:00:00Z"),
    "time_end": ISODate("2024-01-03T00:00:00Z"),
    "value_avg": 25,
    "time_avg": ISODate("2024-01-02T00:00:00Z"),
    "value_min": 20,
    "time_min": ISODate("2024-01-01T12:00:00Z"),
    "value_max": 30,
    "time_max": ISODate("2024-01-02T12:00:00Z")
  },
  "time_values": [/* 原有数组保留,不需要可通过$project删除 */],
  "remaining_time_values": [
    {"time": ISODate("2024-01-01T12:00:00Z"), "value": 20},
    {"time": ISODate("2024-01-02T12:00:00Z"), "value": 30}
  ]
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 05:39:04