Combining multiple sub-documents into a new doc in mongo Combining multiple sub-documents into a new doc in mongo mongodb mongodb

Combining multiple sub-documents into a new doc in mongo


You can definitely do this with aggregate. Let's assume your data is in collection named board, so please replace it with whatever your collection name is.

db.board.aggregate([{$unwind:"$hosts"},{$group:{_id:null, hosts:{$addToSet:"$hosts"}}},{$project:{_id:0, hosts:1}}]).pretty()

it will return

    {        "hosts" : [            {                "name" : "kenrick",                "ip" : "10.3.2.4"            },            {                "name" : "pavel",                "ip" : "10.3.2.3"            },            {                "name" : "mouse",                "ip" : "10.2.2.4"            },            {                "name" : "mickey",                "ip" : "10.2.2.3"            },            {                "name" : "tom",                "ip" : "10.1.2.4"            },            {                "name" : "bob",                "ip" : "10.1.2.3"            }        ]    }


So your basic problem here is that the arrays are contained in separate documents. So while you are correct to $unwind the array for processing, in order to bring the content into a single array you would need to $group the result across documents, and $push the content to the result array:

db.collection.aggregate([    { "$unwind": "$hosts" },    { "$group": {        "_id": null,        "hosts": { "$push": "$hosts" }    }}])

So just as $unwind will "deconstruct" the array elements, the $push accumulator in $group brings "reconstructs" the array. And since there is no other key to "group" on, this brings all the elements into a single array.

Note that a null grouping key is only really practical when the resulting document would not exceed the BSON limit. Otherwise you are better off leaving the individual elements as documents in themselves.

Optionally remove the _id with an additional $project if required.