Mongo convert embedded document to array

Viewed 8466

Is there a way to convert a nested document structure into an array? Below is an example:

Input

"experience" : {
        "0" : {
            "duration" : "3 months",
            "end" : "August 2012",
            "organization" : {
                "0" : {
                    "name" : "Bank of China",
                    "profile_url" : "http://www.linkedin.com/company/13801"
                }
            },
            "start" : "June 2012",
            "title" : "Intern Analyst"
        }
    },

Expected Output:

"experience" : [
           {
            "duration" : "3 months",
            "end" : "August 2012",
            "organization" : {
                "0" : {
                    "name" : "Bank of China",
                    "profile_url" : "http://www.linkedin.com/company/13801"
                }
            },
            "start" : "June 2012",
            "title" : "Intern Analyst"
        }
    ],

Currently I am using a script to iterate over each element, convert them to an array & finally update the document. But it is taking a lot of time, is there a better way of doing this?

4 Answers

For mongoDB version >4.2 :

db.doc.aggregate([{ $match: {'experience.0': { $exists: false } } },
    {$project:{experience:["$experience.0"]}}, { $merge: { into: "doc", on: "_id" }
])

Note : Here we're merging the updated field/document with existing, but not replacing/updating entire document, default behavior of $merge is merge whenMatched document is found, You can pass other options like replace/keepExisting etc.

Ref: $merge

I am not sure, why aren't there any good answers yet.

It's super easy with aggregation "$set", set is used to add a new field. here you can add a new field with same name into an array. So it will override the older field.

Refer below example:

db.collectionName.aggregate[
   // match/other aggregations
   {$set: { "experience": ["$experience"] } }
];
Related