Le pipeline suivant devrait fonctionner pour vous :
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);
});
Le pipeline est structuré de telle manière que votre première étape, le $project
l'étape de l'opérateur, consiste à projeter le champ post_id
à utiliser comme groupe par clé dans la prochaine étape du pipeline. Étant donné que votre schéma est hiérarchique, vous aurez besoin de ce champ pour les documents parent/racine. Le $ifNull
agira comme opérateur de fusion et renverra la valeur de remplacement si le champ n'existe pas dans les documents.
La prochaine étape du pipeline, le $group
l'étape pipeline essaie de regrouper les données pour les traiter. Le $group
L'opérateur de pipeline est similaire à la clause GROUP BY de SQL. En SQL, nous ne pouvons pas utiliser GROUP BY à moins d'utiliser l'une des fonctions d'agrégation. De la même manière, nous devons également utiliser une fonction d'agrégation dans MongoDB. Dans ce cas, vous avez besoin de $push
opérateur pour créer le tableau de commentaires. Les autres champs sont ensuite accumulés en utilisant le $first
opérateur.
La dernière étape consiste à filtrer le tableau des commentaires afin de supprimer le document avec les détails de la publication, qui n'est certainement pas de type commentaire. Ceci est rendu possible grâce à $setDifference
et $map
les opérateurs. Le $map
L'opérateur crée essentiellement un nouveau champ de tableau qui contient des valeurs résultant de la logique évaluée dans une sous-expression pour chaque élément d'un tableau. Le $setDifference
L'opérateur renvoie alors un ensemble avec des éléments qui apparaissent dans le premier ensemble mais pas dans le second ensemble ; c'est-à-dire effectue un complément relatif du deuxième ensemble par rapport au premier. Dans ce cas, il renverra les comments
finaux tableau qui a des éléments non liés aux documents parents via le _id
propriété.