Følgende pipeline burde fungere for dig:
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);
});
Pipelinen er struktureret på en sådan måde, at dit første skridt, $projekt
operatørstadiet, er at projicere feltet post_id
skal bruges som gruppe for nøgle i næste pipelinefase. Da dit skema er hierarkisk, skal du bruge dette felt til overordnede/roddokumenter. $ifNull
operatør vil fungere som sammensmeltningsoperatør og returnere erstatningsværdien, hvis feltet ikke findes i dokumenterne.
Det næste pipeline-trin, kode>$gruppe
pipeline-stadiet forsøger at gruppere dataene for at behandle dem. $group
pipeline-operatoren ligner SQL's GROUP BY-sætning. I SQL kan vi ikke bruge GROUP BY, medmindre vi bruger nogen af aggregeringsfunktionerne. På samme måde skal vi også bruge en aggregeringsfunktion i MongoDB. I dette tilfælde skal du bruge $push
operatør for at oprette kommentararrayet. De andre felter akkumuleres derefter ved hjælp af $first
operatør.
Det sidste trin involverer at tilpasse kommentararrayet, så du fjerner dokumentet med indlægsdetaljerne, som bestemt ikke er af en kommentartype. Dette er gjort muligt gennem $setDifference
og $map
operatører. $map
operatoren opretter i det væsentlige et nyt matrixfelt, der indeholder værdier som et resultat af den evaluerede logik i et underudtryk til hvert element i en matrix. $setDifference
operator returnerer derefter et sæt med elementer, der vises i det første sæt, men ikke i det andet sæt; dvs. udfører et relativt komplement af det andet sæt i forhold til det første. I dette tilfælde vil det returnere de sidste kommentarer
array, der har elementer, der ikke er relateret til de overordnede dokumenter via _id
ejendom.