MongoDB के पास सरणियों के लिए बहुत अच्छा समर्थन है और आपके दस्तावेज़ मोड में बहुत अधिक लचीलापन प्रदान करता है। उदाहरण के लिए, आप दस्तावेज़ों में सरणियाँ एम्बेड कर सकते हैं और दस्तावेज़ों को सरणियों में भी एम्बेड कर सकते हैं, आदि। हालाँकि, सरणियों के साथ काम करने से MongoDB में कई गोचा हैं। इस पोस्ट में, हम कुछ मुद्दों को देखेंगे जो MongoDB में अनुक्रमणिका और सरणियों के साथ है।
मल्टीकी इंडेक्स
MongoDB में, आप सरणी में प्रत्येक तत्व के लिए अनुक्रमणिका प्रविष्टि बनाने के लिए एक सरणी फ़ील्ड को अनुक्रमित कर सकते हैं। परिणामी सूचकांक को 'मल्टीकी' इंडेक्स कहा जाता है। मल्टीकी इंडेक्स को स्केलर वैल्यू या एम्बेडेड दस्तावेज़ों पर बनाया जा सकता है। बहुकुंजी अनुक्रमणिका के बारे में अधिक जानकारी के लिए, यह दस्तावेज़ देखें।
बहु-कुंजी अनुक्रमणिका, हालांकि उपयोगी हैं, कई सीमाएँ हैं:
- यदि आप एक मिश्रित बहुकुंजी अनुक्रमणिका बनाते हैं, तो आपके पास कम से कम एक फ़ील्ड है जो एक सरणी है।
- कंपाउंड इंडेक्स शार्ड की नहीं हो सकता।
- कंपाउंड इंडेक्स हैशेड इंडेक्स नहीं हो सकता।
मल्टीकी इंडेक्स के सबसे दिलचस्प पहलुओं में से एक यह है कि इंडेक्स चौराहे की सीमा की गणना कैसे की जाती है।
इंडेक्स इंटरसेक्ट बाउंड्स
यहां बताया गया है कि कैसे MongoDB दस्तावेज़ इंडेक्स इंटरसेक्ट बाउंड्स को परिभाषित करता है:
"इंडेक्स स्कैन की सीमाएं एक क्वेरी के दौरान खोज करने के लिए एक इंडेक्स के हिस्से को परिभाषित करती हैं। जब एक इंडेक्स पर कई विधेय मौजूद होते हैं, तो MongoDB इन विधेय की सीमाओं को या तो intersection से संयोजित करने का प्रयास करेगा या कंपाउंडिंग छोटी सीमाओं के साथ एक स्कैन तैयार करने के लिए।"
सरणी पर श्रेणी क्वेरी
आइए एक सरल उदाहरण के साथ शुरू करते हैं यह देखने के लिए कि MongoDB सरणियों पर प्रश्नों के लिए अनुक्रमणिका सीमा की गणना कैसे करता है। मान लें कि हमारे पास संग्रह में निम्नलिखित तीन दस्तावेज़ हैं:
{x: 65} {x: 35} {x: [12,95]}
हम निम्नलिखित प्रश्न जारी करते हैं:
db.coll.find({x :{ $gt :22, $lt:55})
क्वेरी काफी सरल है। आप उम्मीद करेंगे कि उत्तर {x:35} होगा लेकिन प्रश्न वापस आ जाएगा:
{x:35} {x:[25,95]}
इसका कारण यह है कि MongoDB सरणियों से कैसे निपटता है। सरणी के समान तत्व को दोनों स्थितियों से मेल खाने की आवश्यकता नहीं है; जब तक प्रत्येक शर्त से मेल खाने वाला एक तत्व है, यह एक मैच है। तो, इस मामले में, सीमाएं [22, इन्फिनिटी] और [-इन्फिनिटी, 55] हैं। चूंकि 'elemMatch' ऑपरेटर का उपयोग नहीं किया जाता है, MongoDB इंडेक्स चौराहे का उपयोग नहीं करता है। MongoDB निर्दिष्ट नहीं करता है कि इनमें से कौन सी श्रेणी [22, इन्फिनिटी] या [-इन्फिनिटी, 55] का उपयोग क्वेरी के निष्पादन के लिए किया जाएगा।
यदि हम इंडेक्स चौराहे का उपयोग करना चाहते हैं, तो हमें निम्नलिखित क्वेरी का उपयोग करने की आवश्यकता है:
db.coll.find(x :{ $elemMatch:{$gt :22,$lt:55}})
जब आप इसका उपयोग करते हैं, तो MongoDB सूचकांक सीमा को काटता है और [22, 55] को सीमा के रूप में उपयोग करता है। जैसा कि अपेक्षित था, यह क्वेरी कोई परिणाम नहीं लौटाती है (elemMatch गैर सरणियों से मेल नहीं खाता)। तो, अनिवार्य रूप से, $elemMatch ऑपरेटर के बिना सरणियों पर श्रेणी प्रश्न काफी बेकार हैं।
कंपाउंड मल्टीकी इंडेक्स - ऐरे और नॉन-एरे फ़ील्ड्स को मिलाना
निम्नलिखित दस्तावेजों के साथ एक संग्रह पर विचार करें:
{item: 35, prices:[250,35]} ...... {item: 106, prices:[1500,65]}
हम इस संग्रह में एक मिश्रित अनुक्रमणिका जोड़ेंगे:
db.ensureIndex({item:1, prices:1});
अब एक साधारण क्वेरी चलाते हैं:
db. coll. find({item: {$gt:12, $lt:65}});
क्वेरी काफी सरल दिखती है, क्योंकि हम एक निश्चित श्रेणी वाले गैर-सरणी आइटम का उपयोग कर रहे हैं। मुझे उम्मीद है कि क्वेरी के लिए इंडेक्स इंटरसेक्ट बाउंड्स आइटम:[[12,65] ] जैसा कुछ होगा, हालांकि, यदि आप एक व्याख्या चलाते हैं तो आप इसे देखेंगे:
"indexBounds" : { "item" : [ [ -Infinity, 65 ] ], "prices" : [ [ { "$minElement" : 1 }, { "$maxElement" : 1 } ] ] },
इसका कारण यह है कि MongoDB यह पता लगाता है कि यह एक बहु-कुंजी अनुक्रमणिका है, और इस तथ्य की परवाह किए बिना कि आपकी क्वेरी किसी सरणी फ़ील्ड का उपयोग नहीं कर रही है, अनुक्रमणिका सीमा प्रतिच्छेदन को संसाधित नहीं करता है। कहानी का नैतिक यह है कि जब आप किसी इंडेक्स में सरणी और गैर-सरणी फ़ील्ड मिलाते हैं, तो हमेशा अपने इंडेक्स चौराहे की सीमाओं पर नजर रखें। संभावना है कि यह कुशल नहीं है।