Poniższy potok powinien działać dla Ciebie:
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);
});
Potok jest skonstruowany w taki sposób, że pierwszym krokiem jest $projekt
etap operatora, polega na wyświetleniu pola post_id
do wykorzystania jako grupowanie według klucza w następnym etapie rurociągu. Ponieważ twój schemat jest hierarchiczny, potrzebujesz tego pola dla dokumentów nadrzędnych/głównych. $ifNull
operator będzie działał jako operator koalescencyjny i zwróci wartość zastępczą, jeśli pole nie istnieje w dokumentach.
Następny krok potoku, $grupa
etap potoku próbuje pogrupować dane w celu ich przetworzenia. $group
Operator potoku jest podobny do klauzuli GROUP BY języka SQL. W SQL nie możemy używać GROUP BY, chyba że używamy którejkolwiek z funkcji agregacji. W ten sam sposób musimy również użyć funkcji agregacji w MongoDB. W takim przypadku potrzebujesz $push
operator do tworzenia tablicy komentarzy. Pozostałe pola są następnie gromadzone za pomocą $pierwszy
operatora.
Ostatnim krokiem jest dopasowanie tablicy komentarzy, aby usunąć dokument ze szczegółami posta, który zdecydowanie nie jest komentarzem. Jest to możliwe dzięki $setDifference
i $map
operatorów. $map
Operator w istocie tworzy nowe pole tablicy, które przechowuje wartości w wyniku oszacowanej logiki w podwyrażeniu do każdego elementu tablicy. $setDifference
operator następnie zwraca zestaw z elementami, które pojawiają się w pierwszym zestawie, ale nie w drugim zestawie; tj. wykonuje względne uzupełnienie drugiego zestawu względem pierwszego. W takim przypadku zwróci końcowe komentarze
tablica, która zawiera elementy niezwiązane z dokumentami nadrzędnymi poprzez _id
właściwość.