Die folgende Pipeline sollte für Sie funktionieren:
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);
});
Die Pipeline ist so aufgebaut, dass Ihr erster Schritt, der $project
Operatorstufe, ist das Feld post_id
zu projizieren als Gruppieren nach Schlüssel in der nächsten Pipelinestufe verwendet werden. Da Ihr Schema hierarchisch ist, benötigen Sie dieses Feld für übergeordnete/Stammdokumente. Der $ifNull
Der Operator fungiert als Koaleszenzoperator und gibt den Ersatzwert zurück, wenn das Feld nicht in den Dokumenten vorhanden ist.
Der nächste Pipeline-Schritt, der $group
Die Pipeline-Phase versucht, die Daten zu gruppieren, um sie zu verarbeiten. Der $group
Der Pipelineoperator ähnelt der GROUP BY-Klausel von SQL. In SQL können wir GROUP BY nicht verwenden, es sei denn, wir verwenden eine der Aggregationsfunktionen. Auf die gleiche Weise müssen wir auch in MongoDB eine Aggregationsfunktion verwenden. In diesem Fall benötigen Sie den $push
-Operator zum Erstellen des Kommentar-Arrays. Die anderen Felder werden dann mithilfe von $first
Betreiber.
Der letzte Schritt besteht darin, das Kommentar-Array zu filtern, sodass Sie das Dokument mit den Beitragsdetails entfernen, das definitiv kein Kommentartyp ist. Dies wird durch $map
Betreiber. Der $map
-Operator erstellt im Wesentlichen ein neues Array-Feld, das Werte als Ergebnis der ausgewerteten Logik in einem Unterausdruck für jedes Element eines Arrays enthält. Der $setDifference
Der Operator gibt dann eine Menge mit Elementen zurück, die in der ersten Menge, aber nicht in der zweiten Menge vorkommen; d.h. führt eine relative Ergänzung des zweiten Satzes relativ zum ersten durch. In diesem Fall werden die abschließenden Kommentare
zurückgegeben Array, das Elemente enthält, die sich nicht über die _id
auf die übergeordneten Dokumente beziehen Eigentum.