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

MongoDB聚合查询:按产品及版本层级分组文档

用MongoDB聚合实现产品-版本的层级分组查询

嘿,刚好我之前做过类似的需求,用MongoDB的聚合管道完全能实现你想要的这种层级式分组结果,下面给你拆解具体的实现步骤和完整代码:

核心思路

我们需要通过两次$group分组先聚合版本数据,再聚合产品数据,最后用$arrayToObject和$replaceRoot把分组结果转换成你要的键值对层级结构。

第一步:按「产品+版本」分组收集文档

这一步先把相同产品相同版本的所有文档归到一组,把组内的文档都存进一个数组里:

{
  $group: {
    _id: {
      product: "$product",
      version: "$version"
    },
    docs: { $push: "$$ROOT" } // 把当前组的所有原始文档推送到docs数组中
  }
}

第二步:按「产品」分组整合版本数据

现在把同一个产品下的不同版本组整合起来,这里要把每个版本对应的文档数组转换成{k: 版本号, v: 文档数组}的格式,方便后续转成对象:

{
  $group: {
    _id: "$_id.product",
    versions: {
      $push: {
        k: "$_id.version",
        v: "$docs"
      }
    }
  }
}

第三步:转换为目标层级结构

用$arrayToObject把版本数组转成以版本号为键的对象,再用$replaceRoot把整个文档替换成以产品名为键的最终结构:

{
  $replaceRoot: {
    newRoot: {
      $arrayToObject: [[{
        k: "$_id",
        v: { $arrayToObject: "$versions" }
      }]]
    }
  }
}

完整聚合查询代码

把上面三个阶段组合起来,完整的查询语句如下:

db.collection.aggregate([
  // 可选:如果需要把字符串格式的created转成Date类型,添加这个阶段
  // {
  //   $addFields: {
  //     created: { $toDate: "$created" }
  //   }
  // },
  // 第一步:按产品+版本分组
  {
    $group: {
      _id: {
        product: "$product",
        version: "$version"
      },
      docs: { $push: "$$ROOT" }
    }
  },
  // 第二步:按产品分组整合版本数据
  {
    $group: {
      _id: "$_id.product",
      versions: {
        $push: {
          k: "$_id.version",
          v: "$docs"
        }
      }
    }
  },
  // 第三步:转换为目标层级结构
  {
    $replaceRoot: {
      newRoot: {
        $arrayToObject: [[{
          k: "$_id",
          v: { $arrayToObject: "$versions" }
        }]]
      }
    }
  }
])

最终结果示例

执行这个查询后,你会得到完全符合需求的结构:

{
  "product1": {
    "1.0": [ {"product": "product1", "version": "1.0", ...}, {"product": "product1", "version": "1.0", ...} ],
    "1.5": [ {"product": "product1", "version": "1.5", ...} ]
  },
  "product2": {
    "2.0": [ {"product": "product2", "version": "2.0", ...} ]
  }
}

另外提个小建议:如果你的created字段是字符串格式,后续要是需要按时间排序或者做时间相关的聚合,可以在最前面加上注释里的$addFields阶段,把它转换成标准的Date类型,这样后续操作会更方便。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 12:03:24