首页 > 解决方案 > 展开子对象数组

问题描述

我在集合中有一组对象。我展示了两个文档来展示这些数组的结构。属性“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

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

谢谢。

标签: mongodb

解决方案


您需要使用$unwindpreserveNullAndEmptyArrays设置为,true因为并非所有文档都包含tipos.ingredientes路径。然后您可以使用$concat$rtrim将名称构建为单个字符串,尝试:

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

推荐阅读