La siguiente canalización debería funcionar para usted:
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);
});
La tubería está estructurada de tal manera que su primer paso, el $project
etapa del operador, es proyectar el campo post_id
para ser utilizado como el grupo por clave en la siguiente etapa de canalización. Dado que su esquema es jerárquico, necesitaría este campo para documentos principales/raíz. El $ifNull
El operador actuará como el operador coalesce y devolverá el valor de reemplazo si el campo no existe en los documentos.
El siguiente paso de canalización, el $group
etapa de canalización intenta agrupar los datos para procesarlos. El $group
El operador de canalización es similar a la cláusula GROUP BY de SQL. En SQL, no podemos usar GROUP BY a menos que usemos alguna de las funciones de agregación. De la misma manera, también tenemos que usar una función de agregación en MongoDB. En este caso, necesita el $push
operador para crear la matriz de comentarios. Luego, los otros campos se acumulan usando $first
operador.
El paso final consiste en ajustar la matriz de comentarios para que elimine el documento con los detalles de la publicación, que definitivamente no es un tipo de comentario. Esto es posible a través de $setDifference
y $map
operadores. El $map
En esencia, el operador crea un nuevo campo de matriz que contiene valores como resultado de la lógica evaluada en una subexpresión para cada elemento de una matriz. El $setDifference
el operador luego devuelve un conjunto con elementos que aparecen en el primer conjunto pero no en el segundo conjunto; es decir, realiza un complemento relativo del segundo conjunto en relación con el primero. En este caso devolverá los comments
finales matriz que tiene elementos no relacionados con los documentos principales a través de _id
propiedad.