इस पर माइलेज भिन्न हो सकता है और यह अच्छी तरह से पता चल सकता है कि "वर्तमान में" जिस प्रक्रिया का आप अनुसरण कर रहे हैं वह कम से कम "सबसे उपयुक्त" है। लेकिन हम शायद अधिक कुशलता से काम कर सकते हैं।
अब आप क्या कर सकते हैं
बशर्ते आपकी सरणियाँ $क्रमबद्ध करें
$push
के साथ संशोधक
, तो आप शायद ऐसा कर सकते हैं:
db.somedb.find(
{
"partn.is_partner": true,
"$where": function() {
return this.partn.slice(-1)[0].is_partner == true;
}
},
{ "partn": { "$slice": -1 } }
)
तो जब तक partn,is_partner
"अनुक्रमित" है यह अभी भी बहुत कुशल है क्योंकि प्रारंभिक क्वेरी स्थिति को एक अनुक्रमणिका का उपयोग करके पूरा किया जा सकता है। जो भाग नहीं कर सकता वह है $where
कोड>
यहां खंड जो जावास्क्रिप्ट मूल्यांकन का उपयोग करता है।
लेकिन $जहां
में वह दूसरा भाग क्या है? केवल सरणी से अंतिम तत्व को "स्लाइसिंग" कर रहा है और is_partner
के मान का परीक्षण कर रहा है संपत्ति यह देखने के लिए कि क्या यह सच है। अगर वह शर्त भी पूरी होती है तो ही दस्तावेज वापस किया जाता है।
$slice
भी है
प्रोजेक्शन ऑपरेटर। यह सरणी से अंतिम तत्व को वापस करने में वही काम करता है। झूठे मिलान पहले ही फ़िल्टर किए जा चुके हैं, इसलिए यह केवल अंतिम तत्व दिखा रहा है जहां सत्य है।
जैसा कि उल्लेख किया गया है, इंडेक्स के साथ संयुक्त, तो यह बहुत जल्दी होना चाहिए क्योंकि दस्तावेज़ पहले ही चुने जा चुके हैं और जावास्क्रिप्ट स्थिति बाकी को फ़िल्टर करती है। ध्यान दें कि मिलान करने के लिए मानक क्वेरी शर्त के साथ किसी अन्य फ़ील्ड के बिना, एक $जहां
खंड एक अनुक्रमणिका का उपयोग नहीं कर सकता है। इसलिए हमेशा अन्य क्वेरी शर्तों के साथ "संयम" का उपयोग करने का प्रयास करें।
भविष्य में आप क्या कर सकते हैं
अगला अप, जबकि लेखन के समय उपलब्ध नहीं है, लेकिन निश्चित रूप से निकट भविष्य में $slice
होगा एकत्रीकरण ढांचे के लिए ऑपरेटर। यह वर्तमान में विकास शाखा में है, लेकिन यहां एक झलक है कि यह कैसे काम करता है:
db.somedb.aggregate([
{ "$match": { "partn.is_partner": true } },
{ "$redact": {
"$cond": {
"if": {
"$anyElementTrue": {
"$map": {
"input": { "$slice": ["$partn",-1] },
"as": "el",
"in": "$$el.is_partner"
}
}
},
"then": "$$KEEP",
"else": "$$PRUNE"
}
}},
{ "$project": {
"partn": { "$slice": [ "$partn",-1 ] }
}}
])
उस $slice
. को मिलाकर एक $redact
के भीतर
चरण यहाँ दस्तावेज़ों को दस्तावेज़ का परीक्षण करते हुए तार्किक स्थिति के साथ फ़िल्टर करने की अनुमति देता है। इस मामले में $slice
एक एकल तत्व सरणी उत्पन्न करता है जो $ पर भेजी जाती है। नक्शा
केवल एक is_partner
extract को निकालने के लिए value (अभी भी एक सरणी के रूप में)। चूंकि यह अभी भी सबसे अच्छा एक तत्व सरणी है, दूसरा परीक्षण है <मजबूत>$anyElementTrue
जो इसे एक विलक्षण बूलियन परिणाम बनाता है, जो के लिए उपयुक्त है। $cond
।
$redact
यहां उस परिणाम पर निर्णय लिया जाता है कि $$KEEP
या $$PRUNE
परिणामों से दस्तावेज़। बाद में हम $slice
. का उपयोग करते हैं प्रोजेक्ट में फिर से फ़िल्टरिंग के बाद सरणी के अंतिम तत्व को वापस करने के लिए।
यह ठीक वैसा ही है जैसा कि JavaScript संस्करण करता है, इस अपवाद के साथ कि यह सभी देशी कोडित ऑपरेटरों का उपयोग कर रहा है, और इसलिए जावास्क्रिप्ट वैकल्पिक की तुलना में थोड़ा तेज होना चाहिए।
दोनों फॉर्म अपेक्षित रूप से आपका पहला दस्तावेज़ लौटाते हैं:
{
"_id" : 0,
"partn" : [
{
"date" : ISODate("2015-07-28T00:59:14.963Z"),
"is_partner" : true
},
{
"date" : ISODate("2015-07-28T01:00:32.771Z"),
"is_partner" : false
},
{
"date" : ISODate("2015-07-28T01:15:29.916Z"),
"is_partner" : true
},
{
"date" : ISODate("2015-08-05T13:48:07.035Z"),
"is_partner" : false
},
{
"date" : ISODate("2015-08-05T13:50:56.482Z"),
"is_partner" : true
}
]
}
दोनों के साथ यहां बड़ी पकड़ यह है कि आपकी सरणी पहले से ही क्रमबद्ध होनी चाहिए ताकि नवीनतम तिथि पहले हो। इसके बिना, आपको $sort
. के लिए एग्रीगेशन फ्रेमवर्क की आवश्यकता होगी सरणी, जैसा कि आप अभी कर रहे हैं।
वास्तव में कुशल नहीं है, इसलिए आपको अपने एरे को "प्री-सॉर्ट" करना चाहिए और प्रत्येक अपडेट पर ऑर्डर बनाए रखना चाहिए।
एक आसान चाल के रूप में, यह वास्तव में सभी संग्रह दस्तावेज़ों में सभी सरणी तत्वों को एक साधारण कथन में पुनः क्रमित करेगा:
db.somedb.update(
{},
{ "$push": {
"partn": { "$each": [], "$sort": { "date": 1 } }
}},
{ "multi": true }
)
इसलिए भले ही आप किसी नए तत्व को किसी सरणी में "धक्का" नहीं दे रहे हैं और केवल एक संपत्ति को अपडेट कर रहे हैं, आप हमेशा उस मूल निर्माण को लागू कर सकते हैं ताकि सरणी को आदेश दिया जा सके कि आप इसे कैसे चाहते हैं।
विचार करने योग्य है क्योंकि इससे चीजें बहुत तेज होनी चाहिए।