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":
{
"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 overwrites the field values as it merges the documents. 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). Also, field c may not have every key listed under 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.
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"}}
])
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.