Ogólne pytanie to uwzględnienie zakresu dla "month"
rozważane wartości, gdzie jest „większy niż” -5
miesięcy „przed” i „mniej niż” +2
miesiące „po” zarejestrowane w "enrolled"
wpisy tablicy.
Problem polega na tym, że ponieważ te wartości są oparte na "dateJoined"
, należy je dostosować do właściwego odstępu między "dateJoined"
i "dateActivated"
. To sprawia, że wyrażenie jest efektywne:
monthsDiff = (yearActivated - yearJoined)*12 + (monthActivated - monthJoined)
where month >= ( startRange + monthsDiff ) and month <= ( endRange + monthsDiff )
and enrolled = "01"
Lub logicznie wyrażone „Miesiące między wyrażonym zakresem skorygowane o liczbę miesięcy różnicy między dołączeniem a aktywacją” .
Jak wspomniano w komentarzu, pierwszą rzeczą, którą musisz tutaj, jest przechowywanie tych wartości dat jako BSON Date
w przeciwieństwie do ich obecnych pozornych wartości „stringowych”. Gdy to zrobisz, możesz zastosować następującą agregację, aby obliczyć różnicę od podanych dat i odpowiednio odfiltrować dostosowany zakres z tablicy przed zliczeniem:
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" ] }
]
}
}
}
}
}
}
}}
])
Dotyczy to więc tego samego $filter
do tablicy, którą próbowałeś, ale teraz uwzględnia również skorygowane wartości w zakresie miesięcy, według których ma być filtrowane.
Aby ułatwić czytanie, stosujemy $let
co pozwala na obliczenie wspólnej wartości uzyskanej dla $$monthsDiff
jak zaimplementowano w zmiennej. Tutaj stosuje się pierwotnie wyjaśnione wyrażenie, używając $year
i $month
aby wyodrębnić te wartości liczbowe z zapisanych dat.
Korzystanie z dodatkowych operatorów matematycznych $add
, $subtract
i $multiply
możesz obliczyć różnicę w miesiącach, a później zastosować do dostosowania wartości „zakresu” w warunkach logicznych za pomocą $gte
i $lte
.
Wreszcie, ponieważ $filter
emituje tablicę tylko wpisów spełniających warunki, aby "zliczyć" stosujemy $size
która zwraca długość "filtrowanej" tablicy, która jest "liczbą" dopasowań.
W zależności od zamierzonego celu całe wyrażenie można również podać w argumencie $sum
jako $group
akumulator, jeśli to rzeczywiście było zamiarem.