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

MongoDB聚合:基于两参数较大值排序并统计最大、最小及平均值

MongoDB聚合需求解决方案

示例文档

[
 {"subdocument": {"value":100,"additionalValue":300}},
 {"subdocument": {"value":100}} // 该文档不存在additionalValue字段
]

需求目标

聚合后得到如下结果:

{
 "largest": // 第一个完整文档,因为300是全局最大值
 "smallest": // 第二个完整文档,因为100是最小值
 "average": 150 // 第一个文档平均值为200,第二个为100,总体平均值150
}

已实现的聚合步骤

{ $sort: { 'subdocument.value': -1 } },
{
  $group: {
    _id: null,
    average: { $avg: '$subdocument.value' },
    items: { $push: '$$ROOT' },
  },
},
{ $set: { largest: { $first: '$items' } } },
{ $set: { smallest: { $last: '$items' } } },
{ $project: { largest: 1, smallest: 1, average: 1 } },

当前问题

  • 现有实现完全没考虑additionalValue字段
  • 不知道怎么用MongoDB表达式获取subdocument.value和subdocument.additionalValue中的较大值(想要类似{ $max: { $larger: ['$subdocument.value', 'subdocument.additonalValue'] }}的效果)
  • additionalValue是可选字段,部分文档可能没有这个字段

解决方案

要搞定这个需求,得先给每个文档算出两个值里的最大值,还有单文档的平均值,再基于这些数据做全局聚合,具体管道如下:

[
  // 先给每个文档计算两个关键值:当前文档的最大值、当前文档的平均值
  {
    $set: {
      docMax: {
        $max: [
          "$subdocument.value",
          // 处理additionalValue不存在的情况,直接用value代替,不影响最大值计算
          { $ifNull: ["$subdocument.additionalValue", "$subdocument.value"] }
        ]
      },
      docAverage: {
        $avg: [
          "$subdocument.value",
          { $ifNull: ["$subdocument.additionalValue", "$subdocument.value"] }
        ]
      }
    }
  },
  // 全局聚合:算总体平均值,同时把所有文档和它们的最大值存起来
  {
    $group: {
      _id: null,
      average: { $avg: "$docAverage" },
      itemsWithMax: { $push: { doc: "$$ROOT", max: "$docMax" } }
    }
  },
  // 找出最大值对应的文档,设为largest
  {
    $set: {
      largest: {
        $first: {
          $sortArray: {
            input: "$itemsWithMax",
            sortBy: { max: -1 }
          }
        }.doc
      }
    }
  },
  // 找出最小值对应的文档,设为smallest
  {
    $set: {
      smallest: {
        $first: {
          $sortArray: {
            input: "$itemsWithMax",
            sortBy: { max: 1 }
          }
        }.doc
      }
    }
  },
  // 清理输出,只保留需要的字段
  {
    $project: {
      _id: 0,
      largest: 1,
      smallest: 1,
      average: 1
    }
  }
]

关键点说明

  • $ifNull专门用来处理additionalValue缺失的情况,直接用value补位,避免计算报错
  • MongoDB里$max本身就支持传数组参数,直接返回数组中的最大值,不需要自定义什么$larger函数
  • 先计算每个文档的局部最大值和平均值,再进行全局聚合,这样既能准确筛选出对应最大/最小的文档,也能算出正确的总体平均值

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 19:05:22