Mario Perez
Mario Perez

Reputation: 93

Unwind children array of objects

I have an array of objects in a collection. I show two documents to show the structure of these array. The property "tipos" is an array of objects. And inside this child array, the property "ingredientes" is another array of objects.

{
    "_id" : ObjectId("5c6c32337acdd946b66f76e9"),
    "name" : "Ensaladas",
    "tipos" : [ 
        {
            "name" : "Rusa",
        }, 
        {
            "name" : "Cesars",
            "ingredientes" : [ 
                {
                    "name" : "Lechuga",
                    "amount" : 20
                },
                {
                    "name" : "Vinagreta",
                    "amount" : 10
                }
            ]
        }, 
        {
            "name" : "Campesina",
            "ingredientes" : [ 
                {
                    "name" : "Beterraga",
                    "amount" : 55
                }
            ]
        }
    ]
},
{
    "_id" : ObjectId("5c6c32337acdd946b66f76e9"),
    "name" : "Carnes",
    "tipos" : [ 
        {
            "name" : "Estofado de pollo",
        }, 
        {
            "name" : "Lomo saltado",
            "ingredientes" : [ 
                {
                    "name" : "Lomo fino",
                    "amount" : 50
                },
                {
                    "name" : "Tomate",
                    "amount" : 15
                }
            ]
        }
    ]
}

I need to unwind it enough to get this result:

Ensaladas  Rusa
Ensaladas  Cesars  Lechuga
Ensaladas  Cesars  Vinagreta
Ensaladas  Campesina  Beterraga
Carnes   Estofado de pollo
Carnes   Lomo saltado  Lomo fino
Carnes   Lomo saltado  Tomate

I have been trying double unwind but not getting the result I need.

Thanks.

Upvotes: 1

Views: 162

Answers (1)

mickl
mickl

Reputation: 49945

You need to use $unwind with preserveNullAndEmptyArrays set to true since not all the documents contain tipos.ingredientes path. Then you can use $concat with $rtrim to build the name as single string, try:

db.col.aggregate([
    { $unwind: "$tipos" },
    { $unwind: { path: "$tipos.ingredientes", preserveNullAndEmptyArrays: true } },
    { $project: { _id: 0, name: { $rtrim: { input: { $concat: [ "$name", " ", "$tipos.name", " ", { $ifNull: [ "$tipos.ingredientes.name", "" ] } ] } } } } }
])

Outputs:

{ "name" : "Ensaladas Rusa" }
{ "name" : "Ensaladas Cesars Lechuga" }
{ "name" : "Ensaladas Cesars Vinagreta" }
{ "name" : "Ensaladas Campesina Beterraga" }
{ "name" : "Carnes Estofado de pollo" }
{ "name" : "Carnes Lomo saltado Lomo fino" }
{ "name" : "Carnes Lomo saltado Tomate" }

Upvotes: 1

Related Questions