एकत्रीकरण ढांचा निश्चित रूप से है सही दृष्टिकोण - सर्वर पर जेएस की आवश्यकता वाली कोई भी चीज़ एक प्रदर्शन समस्या है, जबकि समेकन सभी सर्वर में मूल कोड में चलते हैं।
हालांकि जन्मदिन को आगामी जन्मदिनों की तारीखों में बदलना संभव है और फिर एक श्रेणी क्वेरी करना, मैं इसे स्वयं थोड़ा अलग तरीके से करना पसंद करता हूं।
केवल "पूर्वापेक्षा वर्ष के आज के दिन की गणना करना है"। इसे विभिन्न भाषाओं में करने के कई तरीके हैं, इसलिए यह एकत्रीकरण को कॉल करने से पहले इस नंबर को पास करने से पहले एप्लिकेशन लेयर में किया जा सकता है। मैं अपना todayDayOfYear
call कॉल करने जा रहा था लेकिन मुझे एहसास हुआ कि आप आज के आधार पर एकत्रीकरण ढांचे को इसका पता लगाने दे सकते हैं, इसलिए एकमात्र चर आज की तारीख होगी।
var today=new Date();
मुझे लगता है कि दस्तावेज़ में नाम और जन्मदिन शामिल है, विविधताओं के लिए उचित रूप से समायोजित करें
var p1 = { "$project" : {
"_id" : 0,
"name" : 1,
"birthday" : 1,
"todayDayOfYear" : { "$dayOfYear" : today },
"dayOfYear" : { "$dayOfYear" : "$birthday"}
} };
अब, प्रोजेक्ट करें कि आज से उनके अगले जन्मदिन तक कितने दिन:
var p2 = { "$project" : {
"name" : 1,
"birthday" : 1,
"daysTillBirthday" : { "$subtract" : [
{ "$add" : [
"$dayOfYear",
{ "$cond" : [{"$lt":["$dayOfYear","$todayDayOfYear"]},365,0 ] }
] },
"$todayDayOfYear"
] }
} };
वांछित सीमा के अलावा सभी को बाहर करें:
var m = { "$match" : { "daysTillBirthday" : { "$lt" : 31 } } };
अब इसके साथ एकत्रीकरण चलाएँ:
db.collection.aggregate( p1, p2, m );
उन सभी भाग्यशाली लोगों के नाम, जन्मदिन और जन्मदिन तक की सूची वापस पाने के लिए जिनका जन्मदिन 30 दिनों के भीतर है।
संपादित करें
@ सीन 999 ने एक दिलचस्प बढ़त का मामला पकड़ा - जो लोग 28 फरवरी के बाद एक लीप वर्ष में पैदा हुए थे, उनकी गणना एक से होगी। निम्नलिखित एकत्रीकरण है जो उसके लिए सही ढंग से समायोजित करता है:
var p1 = { "$project" : {
"_id" : 0,
"name" : 1,
"birthday" : 1,
"todayDayOfYear" : { "$dayOfYear" : ISODate("2014-03-09T12:30:51.515Z") },
"leap" : { "$or" : [
{ "$eq" : [ 0, { "$mod" : [ { "$year" : "$birthday" }, 400 ] } ] },
{ "$and" : [
{ "$eq" : [ 0, { "$mod" : [ { "$year" : "$birthday" }, 4 ] } ] },
{ "$ne" : [ 0, { "$mod" : [ { "$year" : "$birthday" }, 100 ] } ] } ] } ] },
"dayOfYear" : { "$dayOfYear" : "$birthday" } } };
var p1p = { "$project" : {
"name" : 1,
"birthday" : 1,
"todayDayOfYear" : 1,
"dayOfYear" : { "$subtract" : [
"$dayOfYear",
{ "$cond" : [ { "$and" : [ "$leap", { "$gt" : [ "$dayOfYear", 59 ] } ] }, 1, 0 ] } ] }
}
}
p2
और m
ऊपर जैसा ही रहें।
टेस्ट इनपुट:
db.birthdays.find({},{name:1,birthday:1,_id:0})
{ "name" : "Ally", "birthday" : ISODate("1975-06-12T00:00:00Z") }
{ "name" : "Ben", "birthday" : ISODate("1968-04-03T00:00:00Z") }
{ "name" : "Mark", "birthday" : ISODate("1949-12-23T00:00:00Z") }
{ "name" : "Paul", "birthday" : ISODate("2014-03-04T15:59:05.374Z") }
{ "name" : "Paul", "birthday" : ISODate("2011-02-07T00:00:00Z") }
{ "name" : "Sean", "birthday" : ISODate("2004-01-31T00:00:00Z") }
{ "name" : "Tim", "birthday" : ISODate("2008-02-28T00:00:00Z") }
{ "name" : "Sandy", "birthday" : ISODate("2005-01-31T00:00:00Z") }
{ "name" : "Toni", "birthday" : ISODate("2009-02-28T00:00:00Z") }
{ "name" : "Sam", "birthday" : ISODate("2005-03-31T00:00:00Z") }
{ "name" : "Max", "birthday" : ISODate("2004-03-31T00:00:00Z") }
{ "name" : "Jen", "birthday" : ISODate("1971-04-03T00:00:00Z") }
{ "name" : "Ellen", "birthday" : ISODate("1996-02-28T00:00:00Z") }
{ "name" : "Fanny", "birthday" : ISODate("1996-02-29T00:00:00Z") }
{ "name" : "Gene", "birthday" : ISODate("1996-03-01T00:00:00Z") }
{ "name" : "Edgar", "birthday" : ISODate("1997-02-28T00:00:00Z") }
{ "name" : "George", "birthday" : ISODate("1997-03-01T00:00:00Z") }
आउटपुट:
db.birthdays.aggregate( p1, p1p, p2, {$sort:{daysTillBirthday:1}});
{ "name" : "Sam", "birthday" : ISODate("2005-03-31T00:00:00Z"), "daysTillBirthday" : 22 }
{ "name" : "Max", "birthday" : ISODate("2004-03-31T00:00:00Z"), "daysTillBirthday" : 22 }
{ "name" : "Ben", "birthday" : ISODate("1968-04-03T00:00:00Z"), "daysTillBirthday" : 25 }
{ "name" : "Jen", "birthday" : ISODate("1971-04-03T00:00:00Z"), "daysTillBirthday" : 25 }
{ "name" : "Ally", "birthday" : ISODate("1975-06-12T00:00:00Z"), "daysTillBirthday" : 95 }
{ "name" : "Mark", "birthday" : ISODate("1949-12-23T00:00:00Z"), "daysTillBirthday" : 289 }
{ "name" : "Sean", "birthday" : ISODate("2004-01-31T00:00:00Z"), "daysTillBirthday" : 328 }
{ "name" : "Sandy", "birthday" : ISODate("2005-01-31T00:00:00Z"), "daysTillBirthday" : 328 }
{ "name" : "Paul", "birthday" : ISODate("2011-02-07T00:00:00Z"), "daysTillBirthday" : 335 }
{ "name" : "Tim", "birthday" : ISODate("2008-02-28T00:00:00Z"), "daysTillBirthday" : 356 }
{ "name" : "Toni", "birthday" : ISODate("2009-02-28T00:00:00Z"), "daysTillBirthday" : 356 }
{ "name" : "Ellen", "birthday" : ISODate("1996-02-28T00:00:00Z"), "daysTillBirthday" : 356 }
{ "name" : "Fanny", "birthday" : ISODate("1996-02-29T00:00:00Z"), "daysTillBirthday" : 356 }
{ "name" : "Edgar", "birthday" : ISODate("1997-02-28T00:00:00Z"), "daysTillBirthday" : 356 }
{ "name" : "Gene", "birthday" : ISODate("1996-03-01T00:00:00Z"), "daysTillBirthday" : 357 }
{ "name" : "George", "birthday" : ISODate("1997-03-01T00:00:00Z"), "daysTillBirthday" : 357 }
{ "name" : "Paul", "birthday" : ISODate("2014-03-04T15:59:05.374Z"), "daysTillBirthday" : 360 }
आप देख सकते हैं कि एक ही जन्मदिन वाले लोगों के जन्मदिन तक जितने दिन होते हैं उतने ही दिन होते हैं चाहे वे लीप वर्ष में पैदा हुए हों या नहीं। अब डिज़ाइन किए गए कट-ऑफ़ के लिए मिलान चरण का प्रदर्शन किया जा सकता है।
संपादित करें
संस्करण 3.5.11 के अनुसार, एकत्रीकरण पाइपलाइन में कई दिनांक हेरफेर अभिव्यक्तियां हैं जो इसे लिखने में काफी आसान बनाती हैं। विशेष रूप से, $dateFromParts अभिव्यक्ति इस एकत्रीकरण की अनुमति देते हुए, विभिन्न भागों से एक तिथि बनाने की अनुमति देती है:
var today = new Date();
var a1 = {$addFields:{
today:{$dateFromParts:{year:{$year:today},month:{$month:today},day:{$dayOfMonth:today}}},
birthdayThisYear:{$dateFromParts:{year:{$year:today}, month:{$month:"$birthday"}, day:{$dayOfMonth:"$birthday"}}},
birthdayNextYear:{$dateFromParts:{year:{$add:[1,{$year:today}]}, month:{$month:"$birthday"}, day:{$dayOfMonth:"$birthday"}}}
}};
var a2 = {$addFields:{
nextBirthday:{$cond:[ {$gte:[ "$birthdayThisYear", "$today"]}, "$birthdayThisYear", "$birthdayNextYear"]}
}};
var p1 = {$project:{
name:1,
birthday:1,
daysTillNextBirthday:{$divide:[
{$subtract:["$nextBirthday", "$today"]},
24*60*60*1000 /* milliseconds in a day */
]},
_id:0
}};
var s1 = {$sort:{daysTillNextBirthday:1}};
db.birthdays.aggregate([ a1, a2, p1, s1 ]);
आप "आज" को किसी भी तिथि (लीप ईयर या नहीं) पर सेट कर सकते हैं और देख सकते हैं कि गणना अब हमेशा सही और बहुत सरल है।