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" : "Ca8ncFgq83RoeD8he",
"some" : "data",
"other" : "things",
"and" : "so on",
},
{
"id" : "vyjgkuNXRN9KkCd5o",
"some" : "data",
"other" : "things",
"and" : "so on",
}
],
},
{
"id" : "TuibXPe5qMvqdMW6q"
"title" : "title 2",
"data" : [
{
"id" : "f5L5zsSNRSQKWoAXL",
"some" : "data",
"other" : "things",
"and" : "so on",
}
],
}
]
}
As you can see, there is a group array, which has also a data array. Now I need a main document like this:
{
"_id" : "sdaGREsfRdfGdFdwG",
"docTitle" : "Document 1"
}
And the next child elements, which would be:
{
"id" : "cdPhkTpMXi8z6TqMT"
"title" : "title 1",
"type" : "group",
"parent" : "sdaGREsfRdfGdFdwG"
},
{
"id" : "TuibXPe5qMvqdMW6q"
"title" : "title 2",
"type" : "group",
"parent" : "sdaGREsfRdfGdFdwG"
}
At least the data elements, which are children of the group-elements:
{
"id" : "Nkspf5kKfPo3axeJA",
"some" : "data",
"other" : "things",
"and" : "so on",
"type" : "element",
"parent" : "cdPhkTpMXi8z6TqMT"
},
{
"id" : "Ca8ncFgq83RoeD8he",
"some" : "data",
"other" : "things",
"and" : "so on",
"type" : "element",
"parent" : "cdPhkTpMXi8z6TqMT"
},
{
"id" : "vyjgkuNXRN9KkCd5o",
"some" : "data",
"other" : "things",
"and" : "so on",
"type" : "element",
"parent" : "cdPhkTpMXi8z6TqMT"
},
{
"id" : "f5L5zsSNRSQKWoAXL",
"some" : "data",
"other" : "things",
"and" : "so on",
"type" : "element",
"parent" : "TuibXPe5qMvqdMW6q"
}
So my attempt would be something like this:
Collection.find({}).forEach(function(doc) { // get all documents
var docID = doc._id;
doc.group.forEach(function(group) { // get all groups
var parent = group.id;
group.type = "group";
group.parent = docID;
group.data.forEach(function(element) { // get all elements
element.type ="element";
element.parent = parent;
});
});
});
1) I don't know how to do that in a better way
2) And I don't know how to save the result back to the collection
Fot the groups:
db.myCol.aggregate([{$unwind:"$group"},
{$project:{_id:"$group.id", some:"$group.some",
parent:"$_id", type:{$literal:"group"}}}])
For the Elements:
db.myCol.aggregate([{$unwind:"$group"},
{$unwind:"$group.data"},
{$project:{_id:"$group.data.id", some:"$group.data.some",
parent:"$group.id", type:{$literal:"element"}}}])
And to your second question: You can add an $out step to the aggregation pipeline at the end. For example: {$out:"outputCol"}