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

MongoDB按字段分组并将子文档合并至父文档的实现方法

解决MongoDB按字段分组并以子文档字段为键合并的问题

Got it, let's walk through how to solve this aggregation task in MongoDB. You want to group your documents by the a field, then merge each group's documents into a parent structure using one of the child document's fields as a key. Let's start with clarifying the input and possible desired outputs, then jump into the aggregation pipeline.

原始输入文档

First, here's your raw data formatted properly:

[
  { "_id" : "1", "a" : "11", "b" : "o11", "c" : "s11" },
  { "_id" : "2", "a" : "22", "b" : "o22", "c" : "s22" },
  { "_id" : "3", "a" : "11", "b" : "o12", "c" : "s12" },
  { "_id" : "4", "a" : "11", "b" : "o13", "c" : "s13" },
  { "_id" : "5", "a" : "22", "b" : "o23", "c" : "s23" }
]

常见的期望输出结构

I'll cover two common scenarios based on what you might mean by "merge subdocuments using a field as the key":

场景1:以b为键,c为对应值

If you want to map each b value directly to its c value under the grouped a field, the result would look like this:

[
  {
    "a": "11",
    "items": {
      "o11": "s11",
      "o12": "s12",
      "o13": "s13"
    }
  },
  {
    "a": "22",
    "items": {
      "o22": "s22",
      "o23": "s23"
    }
  }
]

场景2:以b为键,对应整个子文档

If you want to preserve the full subdocument under each b key, the result would be:

[
  {
    "a": "11",
    "items": {
      "o11": { "_id": "1", "b": "o11", "c": "s11" },
      "o12": { "_id": "3", "b": "o12", "c": "s12" },
      "o13": { "_id": "4", "b": "o13", "c": "s13" }
    }
  },
  {
    "a": "22",
    "items": {
      "o22": { "_id": "2", "b": "o22", "c": "s22" },
      "o23": { "_id": "5", "b": "o23", "c": "s23" }
    }
  }
]

对应的聚合管道

Let's build the pipeline for each scenario.

场景1的聚合代码

db.yourCollectionName.aggregate([
  // Step 1: Group by 'a' and collect { key: b, value: c } pairs
  {
    $group: {
      _id: "$a",
      keyValuePairs: {
        $push: {
          k: "$b", // Use 'b' as the key
          v: "$c" // Use 'c' as the corresponding value
        }
      }
    }
  },
  // Step 2: Convert the array of key-value pairs into an object
  {
    $project: {
      _id: 0, // Hide the default _id from grouping
      a: "$_id", // Rename the grouped _id back to 'a'
      items: { $arrayToObject: "$keyValuePairs" } // Turn the array into a nested object
    }
  }
])

场景2的聚合代码

db.yourCollectionName.aggregate([
  // Step 1: Group by 'a' and collect { key: b, value: full document } pairs
  {
    $group: {
      _id: "$a",
      keyDocPairs: {
        $push: {
          k: "$b", // Use 'b' as the key
          v: { // Include all fields from the original document except 'a' (or include it if needed)
            _id: "$_id",
            b: "$b",
            c: "$c"
          }
        }
      }
    }
  },
  // Step 2: Convert the array of key-document pairs into an object
  {
    $project: {
      _id: 0,
      a: "$_id",
      items: { $arrayToObject: "$keyDocPairs" }
    }
  }
])

关键知识点解释

  • $group: This stage groups documents by the a field, and uses $push to collect the key-value (or key-document) pairs into an array for each group.
  • $arrayToObject: This MongoDB operator takes an array of {k: "...", v: "..."} objects and converts it into a single object where each k becomes a key, mapped to its corresponding v.

Just replace yourCollectionName with the actual name of your collection, and adjust the k and v fields in the $push stage if you want to use a different field as the key (e.g., use c as the key instead of b).

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 07:23:50