Die allgemeine Bitte hier ist, den Bereich für den "Monat"
einzuschließen Werte berücksichtigt, bei denen es "größer als" -5
ist Monate "vor" und "weniger als" +2
Monate "nach", wie im Feld "registriert"
angegeben Array-Einträge.
Das Problem besteht darin, dass diese Werte auf "dateJoined"
basieren , müssen sie um das richtige Intervall zwischen "dateJoined"
angepasst werden und der "dateActivated"
. Dies macht den Ausdruck effektiv:
monthsDiff = (yearActivated - yearJoined)*12 + (monthActivated - monthJoined)
where month >= ( startRange + monthsDiff ) and month <= ( endRange + monthsDiff )
and enrolled = "01"
Oder logisch ausgedrückt "Die Monate zwischen dem ausgedrückten Bereich, angepasst um die Anzahl der Monate zwischen Beitritt und Aktivierung" .
Wie im Kommentar erwähnt, ist das allererste, was Sie hier tun müssen, diese Datumswerte als BSON Date
zu speichern im Gegensatz zu ihren gegenwärtigen scheinbaren "String"-Werten. Sobald dies erledigt ist, können Sie die folgende Aggregation anwenden, um die Differenz aus den angegebenen Daten zu berechnen und den angepassten Bereich vor dem Zählen entsprechend aus dem Array zu filtern:
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" ] }
]
}
}
}
}
}
}
}}
])
Daher gilt dasselbe $filter
zu dem Array, das Sie versucht haben, berücksichtigt jetzt aber auch die angepassten Werte für den Bereich der Monate, nach denen gefiltert werden soll.
Um dies leichter lesbar zu machen, verwenden wir $let
was die Berechnung des gemeinsamen Werts ermöglicht, der für $$monthsDiff
erhalten wird wie in einer Variablen implementiert. Hier wird der ursprünglich erläuterte Ausdruck unter Verwendung von $year angewendet
und $month
um diese numerischen Werte aus den gespeicherten Daten zu extrahieren.
Verwenden der zusätzlichen mathematischen Operatoren $add
, $subtract
und $multiply
Sie können sowohl die Differenz in Monaten berechnen als auch später beantragen, die „Range“-Werte in den logischen Bedingungen anzupassen mit $gte
und $lte
.
Schließlich, weil $filter
gibt ein Array aus, das nur die Einträge enthält, die den Bedingungen entsprechen. Um zu „zählen“, wenden wir $size
die die Länge des "gefilterten" Arrays zurückgibt, was die "Anzahl" der Übereinstimmungen ist.
Abhängig von Ihrem beabsichtigten Zweck kann der gesamte Ausdruck auch als Argument für $group
Akku, wenn das denn tatsächlich so gewollt war.