La pregunta general aquí es incluir el rango para el "month"
valores en consideración donde es "mayor que" el -5
meses "antes" y "menos de" el +2
meses "después" como se registra en el "enrolled"
entradas de matriz.
El problema es que, dado que estos valores se basan en "dateJoined"
, deben ajustarse según el intervalo correcto entre "dateJoined"
y el "dateActivated"
. Esto hace que la expresión sea efectiva:
monthsDiff = (yearActivated - yearJoined)*12 + (monthActivated - monthJoined)
where month >= ( startRange + monthsDiff ) and month <= ( endRange + monthsDiff )
and enrolled = "01"
O expresado lógicamente "Los meses entre el rango expresado ajustado por el número de meses de diferencia entre unirse y activar" .
Como se indica en el comentario, lo primero que debe hacer aquí es almacenar esos valores de fecha como BSON Date
a diferencia de sus valores de "cadena" aparentes actuales. Una vez hecho esto, puede aplicar la siguiente agregación para calcular la diferencia de las fechas proporcionadas y filtrar el rango ajustado en consecuencia de la matriz antes de contar:
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" ] }
]
}
}
}
}
}
}
}}
])
Entonces esto aplica lo mismo $filter
a la matriz que estaba intentando, pero ahora también tiene en cuenta los valores ajustados en el rango de meses para filtrar.
Para que sea más fácil de leer, aplicamos $let
que permite calcular el valor común obtenido para $$monthsDiff
como implementado en una variable. Aquí es donde se aplica la expresión explicada originalmente, usando $year
y $month
para extraer esos valores numéricos de las fechas almacenadas.
Usando los operadores matemáticos adicionales $add
, $subtract
y $multiply
puede calcular la diferencia en meses y luego aplicar para ajustar los valores de "rango" en las condiciones lógicas con $gte
y $lte
.
Finalmente, porque $filter
emite una matriz de solo las entradas que coinciden con las condiciones, para "contar" aplicamos $size
que devuelve la longitud de la matriz "filtrada", que es el "recuento" de coincidencias.
Según el propósito previsto, la expresión completa también se puede proporcionar como argumento para $sum
como $group
acumulador, si entonces era realmente la intención.