Obecným požadavkem zde je zahrnout rozsah pro "month"
hodnoty v úvahu, kde je "větší než" -5
měsíce "před" a "méně než" +2
měsíce "po", jak je zaznamenáno v "enrolled"
položky pole.
Problém je v tom, že tyto hodnoty jsou založeny na "dateJoined"
, je třeba je upravit o správný interval mezi "dateJoined"
a "dateActivated"
. Díky tomu je výraz efektivně:
monthsDiff = (yearActivated - yearJoined)*12 + (monthActivated - monthJoined)
where month >= ( startRange + monthsDiff ) and month <= ( endRange + monthsDiff )
and enrolled = "01"
Nebo logicky vyjádřené "Měsíce mezi vyjádřeným rozsahem upravené o rozdíl počtu měsíců mezi připojením a aktivací" .
Jak je uvedeno v komentáři, úplně první věc, kterou zde musíte udělat, je uložit tyto hodnoty data jako BSON Date
na rozdíl od jejich současných zdánlivých „řetězcových“ hodnot. Jakmile to uděláte, můžete použít následující agregaci k výpočtu rozdílu od dodaných dat a před počítáním odpovídajícím způsobem filtrovat upravený rozsah z pole:
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" ] }
]
}
}
}
}
}
}
}}
])
Platí to tedy stejné $filter
na pole, o které jste se pokoušeli, ale nyní bere v úvahu i upravené hodnoty v rozsahu měsíců, podle kterých se má filtrovat.
Abychom vám usnadnili čtení, použijeme $let
což umožňuje výpočet společné hodnoty získané pro $$monthsDiff
jak je implementováno v proměnné. Zde je použit původně vysvětlený výraz pomocí $year
a $month
extrahovat tyto číselné hodnoty z uložených dat.
Použití dalších matematických operátorů $add
, $subtract
a $multiply
můžete vypočítat rozdíl v měsících a také později použít k úpravě hodnot "rozsahu" v logických podmínkách pomocí $gte
a $lte
.
Konečně, protože $filter
vydává pole pouze záznamů vyhovujících podmínkám, abychom "počítali" použijeme $size
která vrací délku "filtrovaného" pole, což je "počet" shod.
V závislosti na zamýšleném účelu může být celý výraz poskytnut také jako argument pro $sum
jako $group
akumulátor, pokud to byl skutečně záměr.