आप जो यहां पूछ रहे हैं उसके साथ मूल समस्या इस तथ्य पर आती है कि प्रश्न में डेटा "सरणी" के भीतर है, और इसलिए मोंगोडीबी द्वारा इसे कैसे संभाला जाता है, इस बारे में कुछ बुनियादी धारणाएं हैं।
यदि आपने "अवरोही क्रम" में एक प्रकार लागू किया है, तो MongoDB ठीक वही करेगा जो आप पूछते हैं और दस्तावेज़ों को सरणी के भीतर निर्दिष्ट फ़ील्ड के "सबसे बड़े" मान के अनुसार क्रमबद्ध करते हैं:
.sort({ "revisions.created": -1 ))
लेकिन अगर इसके बजाय आप "आरोही" क्रम में क्रमबद्ध करते हैं तो निश्चित रूप से विपरीत सत्य है और "सबसे छोटा" मान माना जाता है।
.sort({ "revisions.created": 1 })
तो ऐसा करने का एकमात्र तरीका यह है कि काम करना जो सरणी में डेटा से अधिकतम तिथि है, और फिर उस परिणाम को क्रमबद्ध करना। इसका मूल रूप से मतलब है .aggregate()
applying को लागू करना , जो उल्का के लिए एक सर्वर साइड ऑपरेशन है, दुर्भाग्य से कुछ इस तरह है:
Collection.aggregate([
{ "$unwind": "$revisions" },
{ "$group": {
"_id": "$_id",
"name": { "$first": "$name" },
"revisions": { "$push": "$revisions" },
"number": { "$first": "$number" }
"maxDate": { "$max": "$revisions.created" }
}},
{ "$sort": { "maxDate": 1 }
])
या सबसे अच्छा MongoDB 3.2 के साथ, जहां $max
सरणी अभिव्यक्ति पर सीधे लागू किया जा सकता है:
Collection.aggregate([
{ "$project": {
"name": 1,
"revisions": 1,
"number": 1,
"maxDate": {
"$max": {
"$map": {
"input": "$revisions",
"as": "el",
"in": "$$el.created"
}
}
}
}},
{ "$sort": { "maxDate": 1 } }
])
लेकिन वास्तव में दोनों इतने महान नहीं हैं, भले ही MongoDB 3.2 दृष्टिकोण में पिछले संस्करणों की तुलना में कम ओवरहेड है, यह अभी भी उतना अच्छा नहीं है जितना आप डेटा और काम से गुजरने की आवश्यकता के कारण प्रदर्शन के मामले में प्राप्त कर सकते हैं। सॉर्ट करने के लिए मान बाहर करें।
तो सर्वश्रेष्ठ . के लिए प्रदर्शन, "हमेशा" ऐसे डेटा को रखें जिसकी आपको सरणी के "बाहर" की आवश्यकता होगी। इसके लिए $max
. है "अपडेट" ऑपरेटर, जो केवल दस्तावेज़ के भीतर एक मान को प्रतिस्थापित करेगा "यदि" प्रदान किया गया मान पहले से मौजूद मौजूदा मान से "अधिक" है। यानी:
Collection.update(
{ "_id": "qTF8kEphNoB3eTNRA" },
{
"$push": {
"revisions": { "created": new Date("2016-02-01") }
},
"$max": { "maxDate": new Date("2016-02-01") }
}
)
इसका मतलब यह है कि आप जो मान चाहते हैं वह "हमेशा" अपेक्षित मूल्य के साथ दस्तावेज़ में पहले से मौजूद होगा, इसलिए यह उस फ़ील्ड पर सॉर्ट करने का एक साधारण मामला है:
.sort({ "maxDate": 1 })
तो मेरे पैसे के लिए, मैं मौजूदा डेटा के बावजूद .aggregate()
. में से किसी एक के साथ जाऊंगा विवरण उपलब्ध हैं, और उन परिणामों का उपयोग प्रत्येक दस्तावेज़ को "maxDate" फ़ील्ड रखने के लिए अद्यतन करने के लिए करें। फिर उस $max
. को लागू करने के लिए सरणी डेटा के सभी परिवर्धन और संशोधनों की कोडिंग बदलें हर बदलाव पर "अपडेट" करें।
गणना के बजाय एक ठोस क्षेत्र होने से हमेशा अधिक समझ में आता है यदि आप इसे अक्सर पर्याप्त उपयोग कर रहे हैं। और रखरखाव काफी सरल है।
किसी भी मामले में, उपरोक्त लागू उदाहरण तिथि पर विचार करते हुए, जो अन्य अधिकतम तिथियां "से कम" है, मेरे लिए सभी रूपों में वापस आ जाएगी:
{
"_id" : "5xF9iDTj3reLDKNHh",
"name" : "Lorem ipsum",
"revisions" : [
{
"number" : 0,
"comment" : "Dolor sit amet",
"created" : ISODate("2016-02-11T01:22:45.588Z")
}
],
"number" : 1,
"maxDate" : ISODate("2016-02-11T01:22:45.588Z")
}
{
"_id" : "qTF8kEphNoB3eTNRA",
"name" : "Consecitur quinam",
"revisions" : [
{
"comment" : "Hoste ad poderiquem",
"number" : 1,
"created" : ISODate("2016-02-11T23:25:46.033Z")
},
{
"number" : 0,
"comment" : "Fagor questibilus",
"created" : ISODate("2016-02-11T01:22:45.588Z")
},
{
"created" : ISODate("2016-02-01T00:00:00Z")
}
],
"number" : 2,
"maxDate" : ISODate("2016-02-11T23:25:46.033Z")
}
जो "maxDate" को ध्यान में रखते हुए पहले दस्तावेज़ को क्रम के शीर्ष पर सही ढंग से रखता है।