2012-06-22 11 views
15

मान लीजिए कि मैं नामक एक संग्रह में निम्नलिखित दस्तावेज़ स्कीमा करते हैं 'उन':MongoDB: एम्बेडेड सरणी के अंदर वस्तुओं को क्वेरी और पुनर्प्राप्त करें?

{ 
    name: 'John', 
    items: [ {}, {}, {}, ... ] 
} 

'आइटम' सरणी निम्न स्वरूप में वस्तुओं में शामिल हैं:

{ 
    item_id: "1234", 
    name: "some item" 
} 

प्रत्येक उपयोगकर्ता से अधिक आइटम हो सकता है 'आइटम' सरणी में एम्बेडेड।

अब, मैं किसी दिए गए उपयोगकर्ता के लिए item_id द्वारा किसी आइटम को लाने में सक्षम होना चाहता हूं।

उदाहरण के लिए, मैं आईडी "1234" के साथ आइटम प्राप्त करना चाहता हूं जो उपयोगकर्ता "जॉन" नाम से है।

क्या मैं इसे mongoDB के साथ कर सकता हूं? मैं अपने शक्तिशाली सरणी अनुक्रमण का उपयोग करना चाहता हूं, लेकिन मुझे यकीन नहीं है कि क्या आप एम्बेडेड सरणी पर क्वेरी चला सकते हैं और उस दस्तावेज़ के बजाय सरणी से वस्तुओं को वापस कर सकते हैं।

मुझे पता है कि मैं उन उपयोगकर्ताओं को ला सकता हूं जिनके पास {users.items.item_id: "1234"} का उपयोग करके एक निश्चित आइटम है। लेकिन मैं वास्तविक आइटम को सरणी से प्राप्त करना चाहता हूं, न कि उपयोगकर्ता।

वैकल्पिक रूप से, क्या इस डेटा को व्यवस्थित करने का एक बेहतर तरीका हो सकता है ताकि मैं आसानी से प्राप्त कर सकूं? मैं अभी भी mongodb के लिए काफी नया हूँ।

किसी भी मदद या सलाह के लिए धन्यवाद जो आप प्रदान कर सकते हैं।

+0

संभव डुप्लिकेट: // stackoverflow.com/questions/3985214/mongodb-extract-only-the-selected-item-in-array) – Foreever

+0

हैलो, @Nebs, क्या आप स्वीकृत उत्तर की समीक्षा कर सकते हैं और इसे बदल सकते हैं? क्योंकि नए मोंगोडब संस्करणों में दो अलग-अलग संग्रहों की आवश्यकता के बिना इस समस्या का समाधान है। –

उत्तर

22

प्रश्न पुराना है, लेकिन समय के बाद प्रतिक्रिया बदल गई है। MongoDB> = 2.2 के साथ, आप कर सकते हैं:

db.users.find({ name: "John"}, { items: { $elemMatch: { item_id: "1234" } } }) 

आप होगा:

{ 
    name: "John", 
    items: 
    [ 
     { 
     item_id: "1234", 
     name: "some item" 
     } 
    ] 
} 

See Documentation of $elemMatch

की [MongoDB सरणी में केवल चयनित आइटम निकालने] (http
+2

ओपी के सवाल का यह सबसे अच्छा जवाब है, मुझे उम्मीद है कि वह इसे देख और बदल देगा, अन्यथा कई लोग स्वीकार किए गए उत्तर को देखेंगे और सोचेंगे कि दो संग्रहों के बिना कोई समाधान नहीं है । –

1

यदि यह एक एम्बेडेड सरणी है, तो आप इसके तत्वों को सीधे पुनर्प्राप्त नहीं कर सकते हैं। पुनर्प्राप्त दस्तावेज़ में उपयोगकर्ता (रूट दस्तावेज़) का रूप होगा, हालांकि सभी फ़ील्ड भर नहीं सकते हैं (आपकी क्वेरी के आधार पर)।

यदि आप केवल उस तत्व को पुनर्प्राप्त करना चाहते हैं, तो आपको इसे एक अलग संग्रह में एक अलग दस्तावेज़ के रूप में स्टोर करना होगा। इसमें एक अतिरिक्त फ़ील्ड होगा, user_id (_id का हिस्सा हो सकता है)। फिर आप जो चाहते हैं उसे करने के लिए तुच्छ है।

एक नमूना दस्तावेज़ इस प्रकार दिखाई देंगे:

{ 
    _id: {user_id: ObjectId, item_id: "1234"}, 
    name: "some item" 
} 

ध्यान दें कि यह संरचना item_id प्रति उपयोगकर्ता की विशिष्टता सुनिश्चित करता है (मुझे यकीन है कि आप इस या नहीं करना चाहता नहीं कर रहा हूँ)।

1) मुझे लगता है कि MongoDB सीखने लोगों के लिए सबसे मुश्किल बात यह है कि संयुक्त राष्ट्र-लर्निंग रिलेशनल सोच है कि वे करने के लिए इस्तेमाल कर रहे हैं:

+2

उत्तर के लिए धन्यवाद। मैं इसके लिए दो संग्रहों का उपयोग करना टालना चाहता था, लेकिन ऐसा लगता है कि यह एकमात्र तरीका है। – nebs

6

चीजों के एक जोड़े को इस बारे में ध्यान देने योग्य हैं। आपका डेटा मॉडल सही दिखता है।

2) आम तौर पर, आप मोंगोडीबी के साथ क्या करते हैं, पूरे दस्तावेज़ को क्लाइंट प्रोग्राम में वापस कर देते हैं, और फिर अपने क्लाइंट प्रोग्रामिंग भाषा का उपयोग कर क्लाइंट पक्ष पर इच्छित दस्तावेज़ के हिस्से की खोज करें।

अपने उदाहरण में, आप पूरे 'उपयोगकर्ता' दस्तावेज़ को लाएंगे और फिर क्लाइंट साइड पर 'आइटम []' सरणी के माध्यम से फिर से शुरू करेंगे।

3) यदि आप केवल 'आइटम []' सरणी वापस करना चाहते हैं, तो आप 'फील्ड चयन' वाक्यविन्यास का उपयोग कर ऐसा कर सकते हैं। विवरण के लिए http://www.mongodb.org/display/DOCS/Querying#Querying-FieldSelection देखें। दुर्भाग्यवश, यह पूरे 'आइटम []' सरणी को वापस कर देगा, न कि सरणी का केवल एक तत्व।

4) इस कार्यक्षमता को जोड़ने के लिए एक मौजूदा जिरा टिकट है: यह https://jira.mongodb.org/browse/SERVER-828 SERVER-828 है। ऐसा लगता है कि इसे नवीनतम 2.1 (विकास) शाखा में जोड़ा गया है: इसका मतलब है कि यह 2.2 जहाजों को रिलीज करते समय उत्पादन के उपयोग के लिए उपलब्ध होगा।

+0

यह एक शानदार जवाब है, मुझे उम्मीद है कि यह अभी भी प्रासंगिक है –

संबंधित मुद्दे