I am finding the MongoDB aggregation framework to be extremely powerful - it seems like a good option to flatten out an object. My schema uses a an array of sub objects in a
There is a request for something like this in jira https://jira.mongodb.org/browse/SERVER-5947 - vote it up if you would like to have this feature.
Meanwhile, there is a work-around if you know up front what the possible values of the keys will be (i.e. all unique values of "category") and I have some sample code on it on my blog.
This would be useful from MongoDB v4.4,
$map
to iterate loop of materials
array$map
to iterate loop of name
and type
fields after converting to array using $objectToArray
, concat your key fields requirement as per fields and value using $concat
,$map
convert returned result from second $map
from array to object using $arrayToObject
$unwind
deconstruct materials
array$group
by null and merge materials
object to one object$replaceRoot
to replace object in rootdb.collection.aggregate([
{
$project: {
materials: {
$map: {
input: "$materials",
as: "m",
in: {
$arrayToObject: [
{
$map: {
input: {
$objectToArray: {
name: "$$m.name",
type: "$$m.type"
}
},
in: {
k: { $concat: ["material", "_", "$$m.category", "_", "$$this.k"] },
v: "$$this.v"
}
}
}
]
}
}
}
}
},
{ $unwind: "$materials" },
{
$group: {
_id: null,
materials: { $mergeObjects: "$materials" }
}
},
{ $replaceRoot: { newRoot: "$materials" } }
])
Playground