[英]Using MergeObjects without overwriting subdocuments
我正在尝试合并聚合管道中的两个字段。
我想改变这个:
{
"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"
}
}
}
对此,无需指定“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"
}
}
}
在mergeObjects
的文档中,它指出:
mergeObjects 在合并文档时会覆盖字段值。 如果要合并的文档包含相同的字段名称,则结果文档中的字段具有为该字段合并的最后一个文档的值。
如何在不指定每个键的情况下合并字段 b 和 c 的子文档(我的真实用例中有 85 个键)。 此外,字段 c 可能没有 b 下列出的每个键。 或者这是不可能的?
您可以使用$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"}}
])
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.