Pertanyaan umum di sini adalah memasukkan rentang untuk "month"
nilai dalam pertimbangan di mana itu "lebih besar dari" -5
bulan "sebelum" dan "kurang dari" +2
bulan "setelah" sebagaimana dicatat dalam "enrolled"
entri larik.
Masalahnya adalah karena nilai ini didasarkan pada "dateJoined"
, mereka perlu disesuaikan dengan interval yang benar antara "dateJoined"
dan "dateActivated"
. Ini membuat ekspresi efektif:
monthsDiff = (yearActivated - yearJoined)*12 + (monthActivated - monthJoined)
where month >= ( startRange + monthsDiff ) and month <= ( endRange + monthsDiff )
and enrolled = "01"
Atau dinyatakan secara logis "Bulan antara rentang yang dinyatakan disesuaikan dengan jumlah bulan perbedaan antara bergabung dan mengaktifkan" .
Seperti yang dinyatakan dalam komentar, hal pertama yang perlu Anda lakukan di sini adalah menyimpan nilai tanggal tersebut sebagai BSON Date
sebagai lawan dari nilai "string" mereka saat ini. Setelah selesai, Anda kemudian dapat menerapkan agregasi berikut untuk menghitung perbedaan dari tanggal yang diberikan dan memfilter rentang yang disesuaikan dari larik sebelum menghitung:
var rangeStart = -5,
rangeEnd = 2;
db.getCollection('enrollments').aggregate([
{ "$project": {
"enrollments": {
"$size": {
"$filter": {
"input": "$enrolled",
"as": "e",
"cond": {
"$let": {
"vars": {
"monthsDiff": {
"$add": [
{ "$multiply": [
{ "$subtract": [
{ "$year": "$dateActivated" },
{ "$year": "$dateJoined" }
]},
12
}},
{ "$subtract": [
{ "$month": "$dateActivated" },
{ "$month": "$dateJoined" }
]}
]
}
},
"in": {
"$and": [
{ "$gte": [ { "$add": [ rangeStart, "$$monthsDiff" ] }, "$$e.month" ] },
{ "$lte": [ { "$add": [ rangeEnd, "$$monthsDiff" ] }, "$$e.month" ] },
{ "$eq": [ "$$e.enrolled", "01" ] }
]
}
}
}
}
}
}
}}
])
Jadi ini berlaku sama $filter
ke larik yang Anda coba, tetapi sekarang memperhitungkan nilai yang disesuaikan pada rentang bulan untuk difilter juga.
Untuk membuatnya lebih mudah dibaca, kami menerapkan $let
yang memungkinkan penghitungan nilai umum yang diperoleh untuk $$monthsDiff
seperti yang diimplementasikan dalam sebuah variabel. Di sinilah ekspresi yang dijelaskan awalnya diterapkan, menggunakan $year
dan $month
untuk mengekstrak nilai numerik tersebut dari tanggal yang disimpan.
Menggunakan operator matematika tambahan $add
, $subtract
dan $multiply
Anda dapat menghitung perbedaan dalam bulan dan juga kemudian menerapkan untuk menyesuaikan nilai "rentang" dalam kondisi logis dengan $gte
dan $lte
.
Akhirnya, karena $filter
memancarkan array hanya entri yang cocok dengan kondisi, untuk "menghitung" kami menerapkan $size
yang mengembalikan panjang larik "terfilter", yang merupakan "jumlah" kecocokan.
Bergantung pada tujuan yang Anda maksudkan, seluruh ekspresi juga dapat diberikan dalam argumen ke $sum
sebagai $group
akumulator, jika memang itu niatnya.