यहाँ सामान्य प्रश्न "माह"
. के लिए श्रेणी शामिल करना है विचाराधीन मान जहां यह -5
. से "अधिक" है महीने "पहले" और "से कम" +2
महीने "बाद" जैसा कि "नामांकित"
. में दर्ज किया गया है सरणी प्रविष्टियाँ।
समस्या यह है कि चूंकि ये मान "dateJoined"
. पर आधारित हैं , उन्हें "dateJoined"
. के बीच सही अंतराल से समायोजित करने की आवश्यकता है और "dateActivated"
. यह अभिव्यक्ति को प्रभावी ढंग से बनाता है:
monthsDiff = (yearActivated - yearJoined)*12 + (monthActivated - monthJoined)
where month >= ( startRange + monthsDiff ) and month <= ( endRange + monthsDiff )
and enrolled = "01"
या तार्किक रूप से व्यक्त "व्यक्त सीमा के बीच के महीनों को शामिल होने और सक्रिय करने के बीच महीनों के अंतर से समायोजित किया जाता है" ।
जैसा कि टिप्पणी में कहा गया है, सबसे पहली चीज जो आपको यहां करने की आवश्यकता है, वह है उन दिनांक मानों को BSON दिनांक
के रूप में संग्रहीत करना। उनके वर्तमान स्पष्ट "स्ट्रिंग" मूल्यों के विपरीत। एक बार ऐसा करने के बाद, आप आपूर्ति की गई तिथियों से अंतर की गणना करने के लिए निम्नलिखित एकत्रीकरण लागू कर सकते हैं और गणना से पहले सरणी से तदनुसार समायोजित सीमा को फ़िल्टर कर सकते हैं:
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
, $subtract
और $multiply
आप महीनों में दोनों के अंतर की गणना कर सकते हैं और बाद में $gte
और $lte
।
अंत में, क्योंकि $filter
शर्तों से मेल खाने वाली केवल प्रविष्टियों की एक सरणी उत्सर्जित करता है, "गिनती" के लिए हम $आकार
जो "फ़िल्टर किए गए" सरणी की लंबाई देता है, जो मैचों की "गिनती" है।
आपके इच्छित उद्देश्य के आधार पर $योग
एक $group
के रूप में
संचायक, यदि वास्तव में इरादा था।