Reputation: 226
I have about MongoDB in unwind operator.
So, I have document like this.
{
"name": "abc",
"report": {
"_2019": {
"May": {
"_9": {
"DATA": [{
"image": "xyz.png",
"object": true
},
{
"image": "abc.png",
"object": true
}
]
},
"_10": {
"DATA": [{
"image": "ejf.png",
"object": false
},
{
"image": "qwe.png",
"object": false
}
]
}
},
"June": {
"_1": {
"DATA": [{
"image": "jsk.png",
"object": false
}]
}
}
},
"_2020": {
"January": {
"_30": {
"DATA": [{
"image": "hhg.png",
"object": false
}]
}
}
}
}
}
And want to format the output for something like this
[{
"image": "xyz.png",
"object": true
}, {
"image": "abc.png",
"object": true
}, {
"image": "ejf.png",
"object": false
}, {
"image": "qwe.png",
"object": false
}, {
"image": "jsk.png",
"object": false
}, {
"image": "hhg.png",
"object": false
}]
The first thing i found is that using unwind, but it only accept array. And the second is using foreach in the programming-side. But i think it's not effective. Is this possible? Thank you.
Upvotes: 6
Views: 2752
Reputation: 49945
The problem here is that the keys like _2020
or January
or _30
are dynamically generated. To access subdocuments from DATA
level you need to get there by using $objectToArray and $map to take values from key-value pairs. After each of these steps you need $unwind and then in the last step you can run $replaceRoot to promote documents from DATA
into root level:
db.col.aggregate([
{
$project: {
data: {
$map: {
input: { $objectToArray: "$report" },
in: "$$this.v"
}
}
}
},
{ $unwind: "$data" },
{
$project: {
data: {
$map: {
input: { $objectToArray: "$data" },
in: "$$this.v"
}
}
}
},
{ $unwind: "$data" },
{
$project: {
data: {
$map: {
input: { $objectToArray: "$data" },
in: "$$this.v"
}
}
}
},
{ $unwind: "$data" },
{ $unwind: "$data.DATA" },
{
$replaceRoot: {
newRoot: "$data.DATA"
}
}
])
Upvotes: 3