De algemene vraag hier is om het bereik op te nemen voor de "maand"
waarden in overweging waar het "groter is dan" de -5
maanden "voor" en "minder dan" de +2
maanden "na" zoals vastgelegd in de "ingeschreven"
array-items.
Het probleem is dat aangezien deze waarden zijn gebaseerd op "dateJoined"
, moeten ze worden aangepast met het juiste interval tussen de "dateJoined"
en de "dateActivated"
. Dit maakt de uitdrukking effectief:
monthsDiff = (yearActivated - yearJoined)*12 + (monthActivated - monthJoined)
where month >= ( startRange + monthsDiff ) and month <= ( endRange + monthsDiff )
and enrolled = "01"
Of logisch uitgedrukt "De maanden tussen het uitgedrukte bereik aangepast door het aantal maanden verschil tussen lid worden en activeren" .
Zoals vermeld in de opmerking, is het allereerste dat u hier moet doen, deze datumwaarden opslaan als een BSON-datum
in tegenstelling tot hun huidige schijnbare "string" -waarden. Zodra dat is gebeurd, kunt u de volgende aggregatie toepassen om het verschil met de opgegeven datums te berekenen en het aangepaste bereik dienovereenkomstig uit de array filteren voordat u gaat tellen:
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" ] }
]
}
}
}
}
}
}
}}
])
Dit is dus van toepassing op dezelfde $filter
naar de array die u probeerde, maar houdt nu ook rekening met de aangepaste waarden voor het bereik van maanden waarop moet worden gefilterd.
Om dit leesbaarder te maken passen we $let
waarmee de gemeenschappelijke waarde kan worden berekend die is verkregen voor $$monthsDiff
zoals geïmplementeerd in een variabele. Hier wordt de oorspronkelijk uitgelegde uitdrukking toegepast, met behulp van $year
en $month
om die numerieke waarden uit de opgeslagen datums te halen.
De aanvullende wiskundige operatoren $add
gebruiken
, $subtract
en $multiply
je kunt zowel het verschil in maanden berekenen als later toepassen om de "bereik"-waarden in de logische voorwaarden aan te passen met $gte
en $lte
.
Ten slotte, omdat $filter
zendt een array uit van alleen de vermeldingen die voldoen aan de voorwaarden, om te "tellen" passen we $maat
die de lengte van de "gefilterde" array retourneert, wat het "aantal" overeenkomsten is.
Afhankelijk van het beoogde doel kan de hele uitdrukking ook als argument worden verstrekt aan $sum
als een $group
accumulator, als dat inderdaad de bedoeling was.