एक पोस्ट में यह बहुत सारे प्रश्न हैं;) मुझे उनके माध्यम से व्यावहारिक क्रम में जाने दें:
- प्रत्येक क्वेरी अधिकतम एक इंडेक्स का उपयोग कर सकती है (शीर्ष स्तर $ या क्लॉज और इस तरह के अपवाद के साथ)। इसमें कोई भी छँटाई शामिल है।
- उपरोक्त के कारण आपको निश्चित रूप से अपनी समस्या के लिए अलग-अलग प्रति-फ़ील्ड अनुक्रमणिका के बजाय एक मिश्रित अनुक्रमणिका की आवश्यकता होगी।
- कम कार्डिनैलिटी फ़ील्ड (इसलिए, आपके डेटासेट में बहुत कम अद्वितीय मान वाले फ़ील्ड) आमतौर पर इंडेक्स में नहीं होने चाहिए क्योंकि उनकी चयनात्मकता बहुत सीमित होती है।
- आपके कंपाउंड इंडेक्स में फ़ील्ड का क्रम मायने रखता है, और इसी तरह आपके कंपाउंड इंडेक्स में प्रत्येक फ़ील्ड की सापेक्ष दिशा (जैसे "{name:1, age:-1}")। mongodb.org पर कंपाउंड इंडेक्स और इंडेक्स फील्ड दिशाओं के बारे में बहुत सारे दस्तावेज हैं, इसलिए मैं इसे यहां नहीं दोहराऊंगा।
- सॉर्ट केवल इंडेक्स का उपयोग करेगा यदि सॉर्ट फ़ील्ड इंडेक्स में है और इंडेक्स में फ़ील्ड सीधे अंतिम फ़ील्ड के बाद है जिसका उपयोग परिणामसेट का चयन करने के लिए किया गया था। ज्यादातर मामलों में यह सूचकांक का अंतिम क्षेत्र होगा।
इसलिए, आपको अपने इंडेक्स में स्टेटस को बिल्कुल भी शामिल नहीं करना चाहिए क्योंकि एक बार इंडेक्स वॉक ने उच्च कार्डिनैलिटी क्षेत्रों के आधार पर दस्तावेजों के विशाल बहुमत को समाप्त कर दिया है, तो ज्यादातर मामलों में 2-3 दस्तावेज बचे होंगे जो शायद ही किसी स्टेटस इंडेक्स द्वारा अनुकूलित किए गए हों। (खासकर जब से आपने उन 2-3 दस्तावेज़ों का उल्लेख किया है, उनके वैसे भी समान स्थिति होने की बहुत संभावना है)।
अब, आपके मामले में प्रासंगिक आखिरी नोट यह है कि जब आप श्रेणी प्रश्नों का उपयोग करते हैं (और आप हैं) तो यह किसी भी तरह से सॉर्ट करने के लिए अनुक्रमणिका का उपयोग नहीं करेगा। एक बार जब आप अपनी क्वेरी का परीक्षण कर लेते हैं तो आप अपने स्पष्टीकरण() के "स्कैनएंडऑर्डर" मान को देखकर इसकी जांच कर सकते हैं। यदि वह मान मौजूद है और सत्य है तो इसका मतलब है कि यह परिणाम को सीधे इंडेक्स का उपयोग करने के बजाय मेमोरी (स्कैन और ऑर्डर) में सॉर्ट करेगा। आपके विशिष्ट मामले में इसे टाला नहीं जा सकता।
तो, आपका सूचकांक इसलिए होना चाहिए:
db.posts.ensureIndex({start:1, end:1})
और आपकी क्वेरी (केवल स्पष्टता के लिए संशोधित आदेश, क्वेरी ऑप्टिमाइज़र आपकी मूल क्वेरी को उसी निष्पादन पथ के माध्यम से चलाएगा लेकिन मैं अनुक्रमित फ़ील्ड को पहले और क्रम में रखना पसंद करता हूं):
db.posts.find({start: {$lt: today}, end: {$gt: today}, status: {$gte:0}}).sort({sortOrder:1})