Tidak segera terlihat tetapi mungkin. Yang perlu Anda lakukan di sini adalah menggabungkan dokumen tingkat atas Anda dengan deretan komentar tanpa menduplikasinya. Berikut adalah pendekatan untuk menggabungkan konten terlebih dahulu sebagai dua larik ke dalam larik tunggal, lalu $unwind
untuk mengelompokkan konten:
db.collection.aggregate([
{ "$group": {
"_id": "$_id",
"author": {
"$addToSet": {
"id": "$_id",
"author": "$author",
"votes": "$votes"
}
},
"comments": { "$first": "$comments" }
}},
{ "$project": {
"combined": { "$setUnion": [ "$author", "$comments" ] }
}},
{ "$unwind": "$combined" },
{ "$group": {
"_id": "$combined.author",
"votes": { "$sum": "$combined.votes" }
}},
{ "$sort": { "votes": -1 } }
])
Yang memberikan output:
{ "_id" : "Jesse", "votes" : 148 }
{ "_id" : "Mirek", "votes" : 135 }
{ "_id" : "Leszke", "votes" : 13 }
Bahkan saat melewatkan $group
stage dan membuat array gabungan dengan cara yang berbeda:
db.collection.aggregate([
{ "$project": {
"combined": {
"$setUnion": [
{ "$map": {
"input": { "$literal": ["A"] },
"as": "el",
"in": {
"author": "$author",
"votes": "$votes"
}
}},
"$comments"
]
}
}},
{ "$unwind": "$combined" },
{ "$group": {
"_id": "$combined.author",
"votes": { "$sum": "$combined.votes" }
}},
{ "$sort": { "votes": -1 } }
])
Mereka menggunakan operator seperti $setUnion
dan bahkan $map
yang diperkenalkan pada MongoDB 2.6. Ini membuatnya lebih sederhana, tetapi masih dapat dilakukan di versi sebelumnya yang tidak memiliki operator tersebut, dengan mengikuti prinsip yang hampir sama:
db.collection.aggregate([
{ "$project": {
"author": 1,
"votes": 1,
"comments": 1,
"type": { "$const": ["A","B"] }
}},
{ "$unwind": "$type" },
{ "$unwind": "$comments" },
{ "$group": {
"_id": {
"$cond": [
{ "$eq": [ "$type", "A" ] },
{
"id": "$_id",
"author": "$author",
"votes": "$votes"
},
"$comments"
]
}
}},
{ "$group": {
"_id": "$_id.author",
"votes": { "$sum": "$_id.votes" }
}},
{ "$sort": { "votes": -1 } }
])
$const
tidak didokumentasikan tetapi ada di semua versi MongoDB di mana kerangka kerja agregasi hadir (dari 2.2). MongoDB 2.6 Memperkenalkan $literal
yang pada dasarnya menautkan ke kode dasar yang sama. Telah digunakan dalam dua kasus di sini untuk menyediakan elemen template untuk larik, atau sebagai memperkenalkan larik untuk bersantai guna memberikan "pilihan biner" di antara dua tindakan.