सभी संभावित forms
. को जाने बिना अपने इच्छित परिणामों के लिए इस संरचना को क्वेरी करना संभव नहीं है नाम पहले से, और क्वेरी में उनका उपयोग करना। यह किसी भी दर पर बहुत गन्दा होगा। उस ने कहा, पढ़िए जैसा कि मैं समझाता हूं कि यह कैसे किया जा सकता है।
इन दस्तावेज़ों की संरचना में एक समस्या है जो आपको कोई भी उचित क्वेरी विश्लेषण करने से रोकेगी। जैसा कि यह खड़ा है आपको किसी भी चीज़ को फ़िल्टर करने के लिए सभी संभावित प्रपत्र नाम फ़ील्ड को जानना होगा।
आपकी वर्तमान संरचना में एक उप-दस्तावेज़ वाले फ़ॉर्म हैं, जिनमें से प्रत्येक कुंजी में एक ही संपत्ति के साथ एक और उप-दस्तावेज़ होता है, status
. आपके forms
. के रूप में इसे पार करना कठिन है आपके द्वारा बनाए गए प्रत्येक दस्तावेज़ के लिए तत्व की मनमानी संरचना है। इसका मतलब है कि उतरने . का पैटर्न status
. तक वह जानकारी जिसे आप अपने संग्रह के प्रत्येक दस्तावेज़ के परिवर्तनों की तुलना करना चाहते हैं।
यहाँ मेरा मतलब पथ से है। किसी भी तत्व में स्थिति प्राप्त करने के लिए आपको निम्न कार्य करने होंगे
दूसरे तत्व के साथ हर समय बदलते रहते हैं। कोई रास्ता नहीं . है करने के लिए वाइल्डकार्ड कुछ इस तरह से नामकरण को स्पष्ट माना जाता है।
इसे आपके फ़ॉर्मों . से डेटा को क्रमानुसार लागू करने का एक आसान तरीका माना जा सकता है लेकिन मुझे एक अधिक लचीला . दिखाई दे रहा है विकल्प। आपको एक दस्तावेज़ संरचना की आवश्यकता है जिसे आप एक मानक पैटर्न में पार कर सकते हैं। यह हमेशा डिजाइन में विचार करने लायक कुछ होता है। निम्नलिखित लें:
{
"_id" : "Tvq444454j",
"name": "Jim",
"forms": [
{
"name": "Jorney",
"status":"closed"
},
{
"name": "Women",
"status":"void"
},
{
"name": "Child",
"status":"closed"
},
{
"name": "Farm",
"status":"closed"
}
]
}
तो दस्तावेज़ की संरचना को forms
. बनाने के लिए बदल दिया गया है तत्व एक ऐरे, और स्थिति फ़ील्ड को "फ़ॉर्म फ़ील्ड" नाम की कुंजी के नीचे रखने के बजाय हमारे पास "फ़ॉर्म फ़ील्ड" name
को कवर करने वाले उप-दस्तावेज़ के रूप में Array के प्रत्येक सदस्य के पास है और status
. तो पहचानकर्ता और स्थिति दोनों को अभी भी एक साथ जोड़ा गया है लेकिन अभी उप-दस्तावेज़ के रूप में दर्शाया गया है। यह सबसे महत्वपूर्ण रूप से इन चाबियों तक पहुंच पथ को बदल देता है, जैसा कि अब दोनों . के लिए है फ़ील्ड का नाम और उसकी स्थिति जो हम कर सकते हैं
क्या यह इसका मतलब यह है कि आप form
. में सभी फ़ील्ड के नाम खोजने के लिए क्वेरी कर सकते हैं या सभी status
forms
. में फ़ील्ड , या यहां तक कि एक निश्चित name
. वाले सभी दस्तावेज़ फ़ील्ड और निश्चित status
. यह बहुत है मूल संरचना के साथ जो किया जा सकता था उससे बेहतर।
अब आपके विशेष मामले में, आप केवल . प्राप्त करना चाहते हैं दस्तावेज़ जहां सभी फ़ील्ड void
नहीं हैं . अब ऐसा करने के लिए एक ही प्रश्न में कोई रास्ता नहीं है क्योंकि इस तरह से एक सरणी में सभी तत्वों की तुलना करने के लिए कोई ऑपरेटर नहीं है और देखें कि क्या वे समान हैं। लेकिन आप दो तरीके अपना सकते हैं:
सभी . के लिए क्वेरी करना पहला और संभवत:उतना प्रभावी नहीं है दस्तावेज़ जिनमें forms
. में एक तत्व होता है जिसकी status
. है "शून्य" का। परिणामी दस्तावेज़ Id के साथ आप एक अन्य क्वेरी जारी कर सकते हैं जो उन दस्तावेज़ों को लौटाती है जो नहीं . करते हैं निर्दिष्ट किए गए आईडी हैं।
db.forms.find({ "forms.status": "void" },{ _id: 1})
db.forms.find({ _id: $not: { $in: [<Object1>,<Object2>,<Object3>,... ] } })
परिणाम आकार को देखते हुए यह संभव नहीं हो सकता है और आम तौर पर एक अच्छा विचार नहीं है क्योंकि बहिष्करण ऑपरेटर $not
मूल रूप से एक पूर्ण स्कैन . के लिए बाध्य कर रहा है संग्रह का, ताकि आप किसी अनुक्रमणिका का उपयोग न कर सकें।
एक अन्य तरीका यह है कि एकत्रीकरण पाइपलाइन का इस प्रकार उपयोग किया जाए:
db.forms.aggregate([
{ "$unwind": "$forms" },
{ "$group": { "_id": "$_id", "status": { "$addToSet": "$forms.status" }}},
{ "$unwind": "$status" },
{ "$sort": { "_id": 1, "status": -1 }},
{ "$group": { "_id": "$_id", "status": { "$first": "$status"}}},
{ "$match":{ "status": "closed" }}
])
बेशक यह मेल खाने वाले दस्तावेज़ों के लिए केवल _id लौटाएगा, लेकिन आप $in के साथ एक क्वेरी जारी कर सकते हैं और पूरे मिलान वाले दस्तावेज़ वापस कर सकते हैं। यह पहले इस्तेमाल किए गए बहिष्करण ऑपरेटर से बेहतर है, और अब हम पूर्ण संग्रह स्कैन से बचने के लिए एक इंडेक्स का उपयोग कर सकते हैं।
अंतिम दृष्टिकोण के रूप में और सर्वश्रेष्ठ . के लिए प्रदर्शन पर विचार करते हुए, आप दस्तावेज़ को फिर से बदल सकते हैं ताकि शीर्ष स्तर पर आप "स्थिति" रखें कि क्या कोई फ़ील्ड "शून्य" या "बंद" में है। तो शीर्ष स्तर पर मूल्य केवल तभी बंद होगा जब सभी आइटम "बंद" और "शून्य" थे यदि कुछ शून्य था, और इसी तरह।
उस अंतिम का अर्थ होगा एक और प्रोग्रामेटिक परिवर्तन, और forms
. में सभी परिवर्तन आइटम को "स्थिति" बनाए रखने के लिए इस फ़ील्ड को भी अपडेट करने की आवश्यकता होगी। हालांकि यह आपके लिए आवश्यक दस्तावेज़ों को खोजने का सबसे कारगर तरीका है और विचार करने योग्य हो सकता है।
संपादित करें :
दस्तावेज़ को मास्टर स्थिति में बदलने के अलावा, संशोधित संरचना पर सबसे तेज़ क्वेरी फ़ॉर्म वास्तव में है:
db.forms.find({ "forms": { "$not": { "$elemMatch": { "status": "void" } } } })