De volgende pijplijn zou voor u moeten werken:
var pipeline = [
{
"$project": {
"title": 1, "body": 1,
"post_id": { "$ifNull": [ "$_post", "$_id" ] }
}
},
{
"$group": {
"_id": "$post_id",
"title": { "$first": "$title" },
"body": { "$first": "$body" },
"comments": {
"$push": {
"_id": "$_id",
"_post": "$post_id",
"body": "$body"
}
}
}
},
{
"$project": {
"title": 1, "body": 1,
"comments": {
"$setDifference": [
{
"$map": {
"input": "$comments",
"as": "el",
"in": {
"$cond": [
{ "$ne": [ "$$el._id", "$$el._post" ] },
"$$el",
false
]
}
}
},
[false]
]
}
}
}
];
Post.aggregate(pipeline, function (err, result) {
if (err) { /* handle error */ };
console.log(result);
});
De pijplijn is zo gestructureerd dat uw eerste stap, de $project
operator stadium, is om het veld post_id
. te projecteren om te worden gebruikt als de groep op sleutel in de volgende pijplijnfase. Aangezien uw schema hiërarchisch is, hebt u dit veld nodig voor bovenliggende/root-documenten. De $ifNull
operator zal optreden als de samenvoegingsoperator en de vervangingswaarde teruggeven als het veld niet bestaat in de documenten.
De volgende pijplijnstap, de $groep
pijplijnfase probeert de gegevens te groeperen om ze te verwerken. De $group
pijplijnoperator is vergelijkbaar met de GROUP BY-clausule van de SQL. In SQL kunnen we GROUP BY niet gebruiken, tenzij we een van de aggregatiefuncties gebruiken. Op dezelfde manier moeten we ook een aggregatiefunctie in MongoDB gebruiken. In dit geval heb je de $first
telefoniste.
De laatste stap omvat het aanpassen van de opmerkingenreeks, zodat u het document met de berichtdetails verwijdert, wat zeker niet van het type opmerking is. Dit wordt mogelijk gemaakt door de $setDifference
en $map
exploitanten. De $map
operator creëert in wezen een nieuw arrayveld dat waarden bevat als resultaat van de geëvalueerde logica in een subexpressie voor elk element van een array. De $setDifference
operator retourneert vervolgens een set met elementen die in de eerste set voorkomen, maar niet in de tweede set; d.w.z. voert een relatieve aanvulling uit van de tweede set ten opzichte van de eerste. In dit geval retourneert het de laatste opmerkingen
array met elementen die niet gerelateerd zijn aan de bovenliggende documenten via de _id
eigendom.