नेस्टेड ऑब्जेक्ट्स की क्वेरी कैसे करें?


204

नेस्टेड ऑब्जेक्ट संकेतन के साथ mongoDB क्वेरी करते समय मुझे एक समस्या है:

db.messages.find( { headers : { From: "reservations@marriott.com" } } ).count()
0
db.messages.find( { 'headers.From': "reservations@marriott.com" }  ).count()
5

मैं नहीं देख सकता कि मैं क्या गलत कर रहा हूँ। मैं नेस्टेड नोटेशन क्वेरी के समान परिणाम वापस करने के लिए नेस्टेड ऑब्जेक्ट नोटेशन की अपेक्षा कर रहा हूं। मैं गलत कहाँ हूँ?

जवाबों:


419

db.messages.find( { headers : { From: "reservations@marriott.com" } } )

यह उन दस्तावेज़ों के लिए प्रश्न है जहाँ headers बराबरी करता है { From: ... } , अर्थात् कोई अन्य फ़ील्ड नहीं है।


db.messages.find( { 'headers.From': "reservations@marriott.com" } )

यह केवल इस headers.Fromक्षेत्र को देखता है , इसमें निहित अन्य क्षेत्रों से प्रभावित नहीं है, या से गायब है headers


डॉट-नोटेशन डॉक्स


क्या "हेडर.फ्रेम" के आसपास के उद्धरणों के बिना ऐसा करने का कोई तरीका है?
ट्राइसिस

मुझे नहीं पता, बस सोच रहा था, और सोचा कि यह कभी-कभी उपयोगी हो सकता है।
कोशिशें

3
@trysis - व्यवहार में, मैंने पाया है कि इनलाइन ऑब्जेक्ट्स की घोषणा करना (जैसे कि मोंगो [ose] डॉक्स में उदाहरण हैं, और ज्यादातर उदाहरणों में) बस वास्तविक दुनिया में पर्याप्त नहीं है। मैंने 'स्थितियां' और 'फ़ील्ड्स' ऑब्जेक्ट्स बनाने की आदत विकसित की है, जिन पर मैं conditions['some.path'] = 'value'अपने व्यावसायिक तर्क में सामान कर सकता हूं, फिर अंत में एक ही क्वेरी चलाएं:find(conditions, fields, callback);
रयान व्हेल

क्या होगा अगर मान लें कि मेरे पास एक कुंजी है जिसमें "domain.com" शामिल है, यह काम नहीं करेगा domains.domain.com:। क्या इस परिदृश्य के लिए कोई वर्कअराउंड है (बिना domain.com को बदलकर कुछ और करने के लिए जैसे domain_com)?
रेंस टिलमैन

1
मेरी अपनी टिप्पणी का उत्तर देते हुए, यह पूरी तरह से अपनी कुंजियों में डॉट्स का उपयोग करने से बचने के लिए सबसे अच्छा है। अपने समाधान में मैंने पूरी तरह से डोमेन की चाबी खाई, और इसके बजाय एक टुकड़ा / सरणी बनाया।
रेंस टिलमैन

20

अलग अलग तरीकों से दो क्वेरी तंत्र काम करते हैं, में सुझाव के रूप में डॉक्स खंड में सहायक दस्तावेज़ों :

क्षेत्र एक एम्बेडेड दस्तावेज़ (यानी, रखती है जब subdocument ), तो आप या तो पूरा निर्दिष्ट कर सकते हैं subdocument "में पहुंच" एक फ़ील्ड का मान, या के रूप subdocument डॉट नोटेशन का उपयोग कर, में अलग-अलग क्षेत्रों के लिए मान निर्दिष्ट करने subdocument :

यदि उप-निक्षेपण फ़ील्ड क्रम सहित बिल्कुल निर्दिष्ट उप-निक्षेपण से मेल खाता है, तो उपनिर्देशकों के भीतर समानता वाले दस्तावेज़ों का चयन करता है।


निम्नलिखित उदाहरण में, क्वेरी उन सभी दस्तावेजों से मेल खाती है, जहाँ फ़ील्ड निर्माता का मान एक सबडैक्ज़िमेंट होता है, जिसमें सटीक मान में केवल companyमान के साथ 'ABC123'फ़ील्ड और मान के addressसाथ फ़ील्ड होता है '123 Street':

db.inventory.find( {
    producer: {
        company: 'ABC123',
        address: '123 Street'
    }
});

8
मैं पागल हो रहा था। यह मुझे काफी असंगत लग रहा है, क्योंकि वस्तुओं को क्वेरी करते समय यह प्रत्यक्ष गुणों को किसी भी क्रम में मिलान किया जा सकता है।
कैपज

7

चूंकि उप-दस्तावेजों के साथ प्रश्नों MongoDB संग्रह के बारे में बहुत भ्रम है , इसलिए मैंने इसके जवाबों को उदाहरणों के साथ समझाने के लायक समझा:

पहले मैंने संग्रह में केवल दो वस्तुओं को सम्मिलित messageकिया है:

> db.messages.find().pretty()
{
    "_id" : ObjectId("5cce8e417d2e7b3fe9c93c32"),
    "headers" : {
        "From" : "reservations@marriott.com"
    }
}
{
    "_id" : ObjectId("5cce8eb97d2e7b3fe9c93c33"),
    "headers" : {
        "From" : "reservations@marriott.com",
        "To" : "kprasad.iitd@gmail.com"
    }
}
>

तो प्रश्न का परिणाम क्या है: db.messages.find({headers: {From: "reservations@marriott.com"} }).count()

यह एक होना चाहिए क्योंकि दस्तावेज़ों के लिए ये प्रश्न जहाँ headersऑब्जेक्ट के बराबर होते हैं {From: "reservations@marriott.com"}, केवल इसमें कोई अन्य फ़ील्ड नहीं होता है या हमें पूरे उप-दस्तावेज़ को फ़ील्ड के मान के रूप में निर्दिष्ट करना चाहिए।

तो @ Edmondo1984 से जवाब के अनुसार

उप-दस्तावेजों के भीतर समानता मिलान दस्तावेजों का चयन करती है यदि उप-क्रम फ़ील्ड के आदेश सहित बिल्कुल निर्दिष्ट उप-दस्तावेज़ से मेल खाता है

उपरोक्त कथनों में से, निम्न क्वेरी परिणाम क्या होना चाहिए?

> db.messages.find({headers: {To: "kprasad.iitd@gmail.com", From: "reservations@marriott.com"}  }).count()
0

और क्या होगा अगर हम दूसरे दस्तावेजों के उप-दस्तावेजों के समान Fromऔर Toअर्थात के क्रम को बदल देंगे ?

> db.messages.find({headers: {From: "reservations@marriott.com", To: "kprasad.iitd@gmail.com"}  }).count()
1

इसलिए, यह क्षेत्र के आदेश सहित बिल्कुल निर्दिष्ट उप-दस्तावेज़ से मेल खाता है

डॉट ऑपरेटर का उपयोग करने के लिए, मुझे लगता है कि यह हर एक के लिए बहुत स्पष्ट है। आइए नीचे प्रश्न के परिणाम देखें:

> db.messages.find( { 'headers.From': "reservations@marriott.com" }  ).count()
2

मुझे उम्मीद है कि उपरोक्त उदाहरण के साथ ये स्पष्टीकरण किसी को उप-दस्तावेजों के साथ क्वेरी खोजने पर अधिक स्पष्टता देगा ।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.