1

I need to convert a collection with nested documents to a model tree structure with parent references. So this is how my structure looks like:

{
    "_id" : "sdaGREsfRdfGdFdwG",
    "docTitle" : "Document 1",
    "group" : [
        {
            "id" : "cdPhkTpMXi8z6TqMT"
            "title" : "title 1",
            "data" : [
                {
                    "id" : "Nkspf5kKfPo3axeJA",
                    "some" : "data",
                    "other" : "things",
                    "and" : "so on",    
                },
                {
                    "id" : "vyjgkuNXRN9KkCd5o",
                    "some" : "data",
                    "any" : "thing",    
                }
            ],

        },
        {
            "id" : "TuibXPe5qMvqdMW6q"
            "title" : "title 2",
            "data" : [
                {
                    "id" : "f5L5zsSNRSQKWoAXL",
                    "some" : "data",

                },
                {
                    "id" : "Ca8ncFgq83RoeD8he",
                    "some" : "data",
                    "other" : "things",

                },
            ],

        }
    ]
}

To get the data elements (which are children of the group-elements), I do this:

db.myCol.aggregate([{$unwind:"$group"}, 
                {$unwind:"$group.data"}, 
                {$project:{_id:"$group.data.id", some:"$group.data.some", 
                           parent:"$group.id", type:{$literal:"element"}}}])

My problem is to get all fields of the data object as the structure of each element differs. There are differnt fields or different number of fields, as the content is dynamic. In the code above I take explicit the field same, but this doesn't really help. I would like to use the complete content and add the fields type and parent.

result

{
    "_id" : "Nkspf5kKfPo3axeJA",
    "some" : "data",
    "other" : "things",
    "and" : "so on",
    "type" : "element",
    "parent" : "cdPhkTpMXi8z6TqMT"
},
{
    "_id" : "vyjgkuNXRN9KkCd5o",
    "some" : "data",
    "any" : "thing",
},
{
    "_id" : "f5L5zsSNRSQKWoAXL",
    "some" : "data",
    "type" : "element",
    "parent" : "TuibXPe5qMvqdMW6q"      
},
{
    "_id" : "Ca8ncFgq83RoeD8he",
    "some" : "data",
    "other" : "things",
    "type" : "element",
    "parent" : "TuibXPe5qMvqdMW6q"  
}

1 Answer 1

2

As per your question you mentioned that you don't know the structure of data element, so to keep data as an array changed your output structure. Here, I post the answer but it not exactly your expected output, but solve the problem of data array dynamic fields using $map in aggregation.

db.myCol.aggregate({
    "$project": {
        "results": {
            "$map": {
                "input": "$group",
                "as": "el",
                "in": {
                    "parent": "$$el.id",
                    "type": {
                        "$literal": "element"
                    },
                    "data": "$$el.data"
                }
            }
        }
    }
}, {
    "$unwind": "$results"
}, {
    "$group": {
        "_id": null,
        "results": {
            "$push": "$results"
        }
    }
}).pretty()

If you unwind again before group like {$wunwind:$results.data} then you will get all data array values.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.