Pipeline berikut akan bekerja untuk Anda:
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);
});
Pipeline terstruktur sedemikian rupa sehingga langkah pertama Anda, $project
tahap operator, adalah memproyeksikan bidang post_id
untuk digunakan sebagai kelompok demi kunci pada tahap pipa berikutnya. Karena skema Anda bersifat hierarkis, Anda memerlukan bidang ini untuk dokumen induk/root. $ifNull
operator akan bertindak sebagai operator gabungan dan mengembalikan nilai pengganti jika kolom tidak ada dalam dokumen.
Langkah pipeline berikutnya, $group
tahap pipa mencoba untuk mengelompokkan data untuk memprosesnya. $group
operator pipa mirip dengan klausa GROUP BY SQL. Dalam SQL, kita tidak dapat menggunakan GROUP BY kecuali kita menggunakan salah satu fungsi agregasi. Dengan cara yang sama, kita juga harus menggunakan fungsi agregasi di MongoDB. Dalam hal ini Anda memerlukan $push
operator untuk membuat array komentar. Kolom lainnya kemudian diakumulasikan menggunakan $first
operator.
Langkah terakhir melibatkan pemasangan array komentar sehingga Anda menghapus dokumen dengan detail posting, yang jelas bukan tipe komentar. Ini dimungkinkan melalui $setDifference
dan $map
operator. $map
operator pada dasarnya menciptakan bidang array baru yang menyimpan nilai sebagai hasil dari logika yang dievaluasi dalam subekspresi untuk setiap elemen array. $setDifference
operator kemudian mengembalikan set dengan elemen yang muncul di set pertama tetapi tidak di set kedua; yaitu melakukan komplemen relatif dari set kedua relatif terhadap yang pertama. Dalam hal ini ia akan mengembalikan comments
terakhir array yang memiliki elemen yang tidak terkait dengan dokumen induk melalui _id
properti.