MongoDB
 sql >> डेटाबेस >  >> NoSQL >> MongoDB

MongoDB में '$या' और '$in' प्रश्नों के साथ छँटाई कैसे काम करती है?

नोट: यह उत्तर MongoDB 3.2.4 पर आधारित है।

explain() के उपयोग की खोज करना सार्थक है मोंगोडीबी में। explain() किसी क्वेरी का आउटपुट (उदा. db.collection.explain().find(...) ) आपको यह जांचने की अनुमति देता है कि क्वेरी में किस इंडेक्स का उपयोग किया गया है, और db.collection.explain('executionStats') आपको यह भी दिखाएगा कि इन-मेमोरी SORT . के कारण क्वेरी सफल होती है या विफल सीमा।

$में

$in क्वेरी को समानता प्रश्नों की एक श्रृंखला के रूप में माना जा सकता है। उदाहरण के लिए, {a: {$in: [1,3,5]}} {a:1}, {a:3}, {a:5} के रूप में सोचा जा सकता है . MongoDB $in को सॉर्ट करेगा क्वेरी के साथ आगे बढ़ने से पहले सरणी, ताकि {$in: [3,5,1]} {$in: [1,3,5]} . से अलग नहीं है ।

आइए मान लें कि संग्रह में एक अनुक्रमणिका है

{a:1, b:1}
  • a . के आधार पर क्रमित करना

      db.coll.find({a: {$in: [1,3,5]}}).sort({a:1})
    

    MongoDB {a:1,b:1} . का उपयोग करने में सक्षम होगा अनुक्रमणिका, चूंकि इस क्वेरी को {a:1}, {a:3}, {a:5} के संघ के रूप में माना जा सकता है प्रश्न। {a:1} . के आधार पर छँटाई इंडेक्स प्रीफ़िक्स के इस्तेमाल की अनुमति देता है , इसलिए MongoDB को इन-मेमोरी सॉर्ट करने की आवश्यकता नहीं है।

    यही स्थिति क्वेरी पर भी लागू होती है:

      db.coll.find({a: {$in: [1,3,5]} ,b:{$gte:1, $lt:2}}).sort({a:1})
    

    चूंकि sort({a:1}) अनुक्रमणिका उपसर्ग का भी उपयोग करता है (a इस मामले में), एक इन-मेमोरी SORT इसलिए मंच की आवश्यकता नहीं है।

  • b के आधार पर छांटना

    a . के आधार पर छांटने की तुलना में यह अधिक दिलचस्प मामला है . उदाहरण के लिए:

      db.coll.find({a: {$in: [1,3,5]}}).sort({b:1})
    

    explain() इस क्वेरी के आउटपुट में SORT_MERGE . नामक एक चरण होगा . याद रखें कि find() क्वेरी के हिस्से को {a:1}, {a:3}, {a:5} के रूप में माना जा सकता है ।

    क्वेरी db.coll.find({a:1}).sort({b:1}) इन-मेमोरी SORT की आवश्यकता नहीं है {a:1,b:1} . की प्रकृति के कारण चरण अनुक्रमणिका:अर्थात्, MongoDB बस (क्रमबद्ध) अनुक्रमणिका पर चल सकता है और b द्वारा क्रमबद्ध दस्तावेज़ लौटा सकता है a . पर समानता पैरामीटर को संतुष्ट करने के बाद . उदा., प्रत्येक a . के लिए , कई b हैं जो पहले से ही b . द्वारा क्रमबद्ध हैं सूचकांक के कारण।

    $in . का उपयोग करना , समग्र क्वेरी के बारे में सोचा जा सकता है:

    • db.coll.find({a:1}).sort({b:1})
    • db.coll.find({a:3}).sort({b:1})
    • db.coll.find({a:5}).sort({b:1})
    • उपरोक्त व्यक्तिगत क्वेरी परिणाम लें, और b . के मान का उपयोग करके मर्ज करें . क्वेरी इन-मेमोरी सॉर्ट चरण की आवश्यकता नहीं है क्योंकि अलग-अलग क्वेरी परिणाम पहले से ही b . द्वारा क्रमबद्ध हैं . MongoDB को केवल (पहले से क्रमबद्ध) उप-क्वेरी परिणामों को एक परिणाम में मर्ज करने की आवश्यकता है।

    इसी तरह, क्वेरी

      db.coll.find({a: {$in: [1,3,5]} ,b:{$gte:1, $lt:2}}).sort({b:1})
    

    SORT_MERGE . का भी उपयोग करता है मंच और ऊपर की क्वेरी के समान ही है। अंतर यह है कि व्यक्तिगत क्वेरी की श्रेणी . के आधार पर दस्तावेज़ों को आउटपुट करती है b (प्रत्येक . के बजाय b ) प्रत्येक a . के लिए (जिसे b . द्वारा क्रमबद्ध किया जाएगा इंडेक्स {a:1,b:1} . के कारण ) इसलिए, क्वेरी को इन-मेमोरी सॉर्ट चरण की आवश्यकता नहीं है।

$या

$or . के लिए अनुक्रमणिका का उपयोग करने के लिए क्वेरी, हर खंड $or . में एक्सप्रेशन के साथ एक इंडेक्स जुड़ा होना चाहिए . यदि यह आवश्यकता पूरी हो जाती है, तो क्वेरी के लिए SORT_MERGE . को नियोजित करना संभव है स्टेज बिल्कुल एक $in . की तरह सवाल। उदाहरण के लिए:

db.coll.explain().find({$or:[{a:1},{a:3},{a:5}]}).sort({b:1})

लगभग समान क्वेरी योजना, अनुक्रमणिका उपयोग और SORT_MERGE . होगा चरण जैसा कि $in . में है ऊपर उदाहरण। अनिवार्य रूप से, क्वेरी के बारे में सोचा जा सकता है:

  • db.coll.find({a:1}).sort({b:1})
  • db.coll.find({a:3}).sort({b:1})
  • db.coll.find({a:5}).sort({b:1})
  • उपरोक्त व्यक्तिगत क्वेरी परिणाम लें, और b . के मान का उपयोग करके मर्ज करें ।

बिलकुल $in . की तरह उदाहरण पहले।

हालांकि, यह प्रश्न:

db.coll.explain().find({$or:[{a:1},{b:1}]}).sort({b:1})

किसी भी अनुक्रमणिका का उपयोग नहीं कर सकते (चूंकि हमारे पास {b:1} . नहीं है अनुक्रमणिका)। इस क्वेरी के परिणामस्वरूप एक संग्रह स्कैन होगा, और इसके परिणामस्वरूप एक इन-मेमोरी सॉर्ट चरण होगा चूंकि किसी अनुक्रमणिका का उपयोग नहीं किया जाता है।

अगर, हालांकि, हम इंडेक्स {b:1} . बनाते हैं , क्वेरी इस प्रकार आगे बढ़ेगी:

  • db.coll.find({a:1}).sort({b:1})
  • db.coll.find({b:1}).sort({b:1})
  • उपरोक्त व्यक्तिगत क्वेरी परिणाम लें, और b . के मान का उपयोग करके मर्ज करें (जो पहले से ही दोनों उप-प्रश्नों में क्रमबद्ध है, अनुक्रमणिका {a:1,b:1} के कारण और {b:1} )।

और MongoDB {a:1} . के परिणामों को मिलाएगा और {b:1} क्वेरीज़ और परिणामों पर मर्ज करें। विलय की प्रक्रिया रैखिक समय है, उदा। O(n)

अंत में, $or . में क्वेरी, प्रत्येक शब्द में sort() . सहित एक इंडेक्स होना चाहिए मंच। अन्यथा, MongoDB को इन-मेमोरी सॉर्ट करना होगा।




  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. एकल क्वेरी में मोंगोडब में 2 संग्रह से डेटा प्राप्त करें

  2. MongoDB E11000 डुप्लिकेट कुंजी त्रुटि

  3. क्या मैं डिफ़ॉल्ट मोंगोडीबी इंडेक्स हटा सकता हूं?

  4. MongoDB:सभी अद्वितीय टैग की सूची प्राप्त करने का एक अच्छा तरीका क्या है?

  5. MongoDB में स्ट्रिंग के रूप में ग्रिड को संग्रहीत करने में क्या कमियां हैं?