展开子对象数组

时间:2019-02-19 20:32:16

标签: mongodb

我在集合中有一组对象。我展示了两个文档来展示这些数组的结构。 属性“ tipos”是一个对象数组。在此子数组中,属性“ ingredientes”是另一个对象数组。

{
    "_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
                }
            ]
        }
    ]
}

我需要充分放松才能获得此结果:

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

我一直在尝试双重放松,但没有获得所需的结果。

谢谢。

1 个答案:

答案 0 :(得分:1)

您需要使用preserveNullAndEmptyArrays设置为true的{​​{3}},因为并非所有文档都包含tipos.ingredientes路径。然后,您可以将RFC 7617$unwind结合使用以将名称构建为单个字符串,请尝试:

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", "" ] } ] } } } } }
])

输出:

{ "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" }