Anda mulai berpikir di sepanjang garis yang benar di sini saat Anda menuju ke arah yang benar. Mengubah pola pikir SQL Anda, "berbeda" sebenarnya hanyalah cara lain untuk menulis $group
operasi dalam kedua bahasa. Itu berarti Anda memiliki dua operasi grup terjadi di sini dan, dalam istilah saluran agregasi, dua tahap saluran.
Hanya dengan dokumen yang disederhanakan untuk divisualisasikan:
{
"campaign_id": "A",
"campaign_name": "A",
"subscriber_id": "123"
},
{
"campaign_id": "A",
"campaign_name": "A",
"subscriber_id": "123"
},
{
"campaign_id": "A",
"campaign_name": "A",
"subscriber_id": "456"
}
Masuk akal bahwa untuk kombinasi "kampanye" yang diberikan, jumlah total dan jumlah "berbeda" masing-masing adalah "3" dan "2". Jadi hal logis yang harus dilakukan adalah "mengelompokkan" semua nilai "subscriber_id" terlebih dahulu dan menyimpan jumlah kemunculan untuk masing-masing, lalu sambil memikirkan "pipa", "total" jumlah itu per "kampanye" dan kemudian hitung saja " berbeda" kemunculan sebagai nomor terpisah:
db.campaigns.aggregate([
{ "$match": { "subscriber_id": { "$ne": null }}},
// Count all occurrences
{ "$group": {
"_id": {
"campaign_id": "$campaign_id",
"campaign_name": "$campaign_name",
"subscriber_id": "$subscriber_id"
},
"count": { "$sum": 1 }
}},
// Sum all occurrences and count distinct
{ "$group": {
"_id": {
"campaign_id": "$_id.campaign_id",
"campaign_name": "$_id.campaign_name"
},
"totalCount": { "$sum": "$count" },
"distinctCount": { "$sum": 1 }
}}
])
Setelah "grup" pertama, dokumen keluaran dapat divisualisasikan seperti ini:
{
"_id" : {
"campaign_id" : "A",
"campaign_name" : "A",
"subscriber_id" : "456"
},
"count" : 1
}
{
"_id" : {
"campaign_id" : "A",
"campaign_name" : "A",
"subscriber_id" : "123"
},
"count" : 2
}
Jadi dari "tiga" dokumen dalam sampel, "2" milik satu nilai yang berbeda dan "1" untuk yang lain. Ini masih bisa dijumlahkan dengan $sum
untuk mendapatkan total pencocokan dokumen yang Anda lakukan pada tahap berikut, dengan hasil akhir:
{
"_id" : {
"campaign_id" : "A",
"campaign_name" : "A"
},
"totalCount" : 3,
"distinctCount" : 2
}
Analogi yang sangat bagus untuk pipa agregasi adalah pipa unix "|" operator, yang memungkinkan "rantai" operasi sehingga Anda dapat meneruskan output dari satu perintah ke input berikutnya, dan seterusnya. Mulai memikirkan persyaratan pemrosesan Anda dengan cara itu akan membantu Anda memahami operasi dengan alur agregasi dengan lebih baik.