A pergunta geral aqui é incluir o intervalo para o
"month"
valores em consideração onde é "maior que" o -5
meses "antes" e "menor que" o +2
meses "depois" conforme registrado no "enrolled"
entradas de matriz. O problema é que, como esses valores são baseados em
"dateJoined"
, eles precisam ser ajustados pelo intervalo correto entre o "dateJoined"
e o "dateActivated"
. Isso torna a expressão efetivamente:monthsDiff = (yearActivated - yearJoined)*12 + (monthActivated - monthJoined)
where month >= ( startRange + monthsDiff ) and month <= ( endRange + monthsDiff )
and enrolled = "01"
Ou expresso logicamente "Os meses entre o intervalo expresso ajustado pelo número de meses de diferença entre a adesão e a ativação" .
Conforme declarado no comentário, a primeira coisa que você precisa fazer aqui é armazenar esses valores de data como uma
BSON Date
em oposição aos seus valores aparentes de "string" atuais. Feito isso, você pode aplicar a seguinte agregação para calcular a diferença das datas fornecidas e filtrar o intervalo ajustado de acordo com a 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" ] }
]
}
}
}
}
}
}
}}
])
Portanto, isso se aplica ao mesmo
$filter
para a matriz que você estava tentando, mas agora leva em consideração os valores ajustados no intervalo de meses para filtrar também. Para facilitar a leitura, aplicamos
$let
que permite o cálculo do valor comum obtido para $$monthsDiff
como implementado em uma variável. Aqui é onde a expressão explicada originalmente é aplicada, usando $year
e $month
para extrair esses valores numéricos das datas armazenadas. Usando os operadores matemáticos adicionais
$add
, $subtract
e $multiply
você pode calcular a diferença em meses e também aplicar posteriormente para ajustar os valores de "intervalo" nas condições lógicas com $gte
e $lte
. Finalmente, porque
$filter
emite uma matriz apenas das entradas que correspondem às condições, para "contar" aplicamos $size
que retorna o comprimento da matriz "filtrada", que é a "contagem" de correspondências. Dependendo do objetivo pretendido, a expressão inteira também pode ser fornecida como argumento para
$sum
como um $group
acumulador, se então era de fato a intenção.