简体   繁体   English

使用 MergeObjects 而不覆盖子文档

[英]Using MergeObjects without overwriting subdocuments

I'm trying to merge two fields in my aggregation pipeline.我正在尝试合并聚合管道中的两个字段。

I want to transform this:我想改变这个:

{
   "a": 1,
   "b": {
      "first": {
          "property_a": "some_value",
          "property_b": "some_value",
          "property_c": "some_value"
      },
      "second": {
          "property_a": "some_value",
          "property_b": "some_value",
          "property_c": "some_value"
      },
      "third": {
          "property_a": "some_value",
          "property_b": "some_value",
          "property_c": "some_value"
      },
      "fiftieth": {
          "property_a": "some_value",
          "property_b": "some_value",
          "property_c": "some_value"
      }
   },
   "c": {
      "first": {
          "property_x": "some_value",
          "property_y": "some_value"
      },
      "second": {
          "property_x": "some_value",
          "property_y": "some_value"
      },
      "fiftieth": {
          "property_x": "some_value",
          "property_y": "some_value"
      }
   }
}

Into this, without having to specify every key listed under "b":对此,无需指定“b”下列出的每个键:

{
   "a": 1,
   "b": {
      "first": {
          "property_a": "some_value",
          "property_b": "some_value",
          "property_c": "some_value",
          "property_x": "some_value",
          "property_y": "some_value"
      },
      "second": {
          "property_a": "some_value",
          "property_b": "some_value",
          "property_c": "some_value",
          "property_x": "some_value",
          "property_y": "some_value"
      },
      "third": {
          "property_a": "some_value",
          "property_b": "some_value",
          "property_c": "some_value"
      },
      "fiftieth": {
          "property_a": "some_value",
          "property_b": "some_value",
          "property_c": "some_value",
          "property_x": "some_value",
          "property_y": "some_value"
      }
   }
}

In the documentation for mergeObjects , it states:mergeObjects的文档中,它指出:

mergeObjects overwrites the field values as it merges the documents. mergeObjects 在合并文档时会覆盖字段值。 If documents to merge include the same field name, the field, in the resulting document, has the value from the last document merged for the field.如果要合并的文档包含相同的字段名称,则结果文档中的字段具有为该字段合并的最后一个文档的值。

How can I merge the subdocuments of fields b and c without specifying every key (there are 85 keys in my real world use case).如何在不指定每个键的情况下合并字段 b 和 c 的子文档(我的真实用例中有 85 个键)。 Also, field c may not have every key listed under b.此外,字段 c 可能没有 b 下列出的每个键。 Or is this not possible?或者这是不可能的?

You could use $objectToArray to convert the objects to k,v pairs, combine and $unwind them, $group by the key name and merge the documents, then $group by the _id to collect the keys back together.您可以使用$objectToArray将对象转换为 k,v 对,组合和$unwind它们,通过键名$group并合并文档,然后通过 _id 使用$group将键收集在一起。

db.collection.aggregate([
  {$addFields: {
      combined: {
        $concatArrays: [
          {$objectToArray: "$b"},
          {$objectToArray: "$c"}
        ]
      }
  }},
  {$unwind: "$combined"},
  {$group: {
      _id: {_id: "$_id", key: "$combined.k"},
      doc: {$first: "$$ROOT"},
      v: {$mergeObjects: "$combined.v"}
  }},
  {$group: {
      _id: "$_id._id",
      doc: {$first: "$doc"},
      combined: {$push: {
          k: "$_id.key",
          v: "$v"
      }}
  }},
  {$addFields: {"doc.b": {$arrayToObject: "$combined"}}},
  {$project: {
    combined: 0,
    "doc.c": 0
  }},
  {$replaceRoot: {newRoot: "$doc"}}
])

Playground操场

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM