ここでの一般的な質問は、 "month"
の範囲を含めることです。 -5
より「大きい」場合の考慮値 +2
の「前」および「未満」の月 "enrolled"
内に記録された「後」の月 配列エントリ。
問題は、これらの値が "dateJoined"
に基づいているためです。 、 "dateJoined"
間の正しい間隔で調整する必要があります および"dateActivated"
。これにより、表現が効果的になります:
monthsDiff = (yearActivated - yearJoined)*12 + (monthActivated - monthJoined)
where month >= ( startRange + monthsDiff ) and month <= ( endRange + monthsDiff )
and enrolled = "01"
または、論理的に表現された「参加とアクティブ化の月数の差によって調整された、表現された範囲間の月数」 。
コメントで述べたように、ここで最初に行う必要があるのは、これらの日付値を BSON Date
として保存することです。 現在の見かけの「文字列」値とは対照的です。それが完了したら、次の集計を適用して、指定された日付との差を計算し、カウントする前に配列からそれに応じて調整された範囲をフィルタリングできます。
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" ] }
]
}
}
}
}
}
}
}}
])
したがって、これは同じ $ filter
に適用されます。
試行していた配列に対して、月の範囲で調整された値も考慮に入れてフィルタリングします。
これを読みやすくするために、 $ let
>
これにより、 $$ monthsDiff
で取得された共通の値を計算できます。 変数に実装されているとおり。ここで、 $ yearを使用して、最初に説明した式が適用されます。
および $ month
保存された日付からこれらの数値を抽出します。
追加の数学演算子を使用する $ add
、 $ extract
および $ multiply
月単位の差を計算し、後で $ gte
および $ lte
。
最後に、 $ filter
条件に一致するエントリのみの配列を出力します。「カウント」するために、 $ size
これは、一致の「カウント」である「フィルター処理された」配列の長さを返します。
目的に応じて、式全体を<の引数として指定することもできます。 code> $ sum
$ group
として
アキュムレータ、それが実際に意図されていた場合。