2013-04-24 9 views
51

मेरे पास दो संग्रह हैं। पहला संग्रह छात्रों में शामिल हैं:मोंगो डीबी: कैसे पता लगाना है कि किसी सरणी फ़ील्ड में कोई तत्व है या नहीं?

{ "_id" : ObjectId("51780f796ec4051a536015cf"), "name" : "John" } 
{ "_id" : ObjectId("51780f796ec4051a536015d0"), "name" : "Sam" } 
{ "_id" : ObjectId("51780f796ec4051a536015d1"), "name" : "Chris" } 
{ "_id" : ObjectId("51780f796ec4051a536015d2"), "name" : "Joe" } 

दूसरा संग्रह पाठ्यक्रमों में शामिल हैं:

{ 
     "_id" : ObjectId("51780fb5c9c41825e3e21fc4"), 
     "name" : "CS 101", 
     "students" : [ 
       ObjectId("51780f796ec4051a536015cf"), 
       ObjectId("51780f796ec4051a536015d0"), 
       ObjectId("51780f796ec4051a536015d2") 
     ] 
} 
{ 
     "_id" : ObjectId("51780fb5c9c41825e3e21fc5"), 
     "name" : "Literature", 
     "students" : [ 
       ObjectId("51780f796ec4051a536015d0"), 
       ObjectId("51780f796ec4051a536015d0"), 
       ObjectId("51780f796ec4051a536015d2") 
     ] 
} 
{ 
     "_id" : ObjectId("51780fb5c9c41825e3e21fc6"), 
     "name" : "Physics", 
     "students" : [ 
       ObjectId("51780f796ec4051a536015cf"), 
       ObjectId("51780f796ec4051a536015d0") 
     ] 
} 

प्रत्येक पाठ्यक्रम दस्तावेज़ students सरणी जो पाठ्यक्रम के लिए पंजीकृत छात्रों की एक सूची है शामिल हैं। जब कोई छात्र किसी वेब पेज पर पाठ्यक्रम देखता है तो उसे यह देखने की ज़रूरत होती है कि क्या वह पहले से ही पाठ्यक्रम के लिए पंजीकृत है या नहीं। ऐसा करने के लिए, जब courses संग्रह छात्र की ओर से पूछताछ की जाती है, तो हमें यह पता लगाना होगा कि students सरणी में पहले से ही छात्र का ऑब्जेक्ट आईडी है। क्या छात्र ObjectIdstudents सरणी से केवल तभी प्राप्त करने के लिए एक खोज क्वेरी के प्रक्षेपण में निर्दिष्ट करने का कोई तरीका है?

मैंने यह देखने की कोशिश की कि क्या मैं $ elemMatch ऑपरेटर कर सकता हूं लेकिन यह उप-दस्तावेजों की एक सरणी के लिए तैयार है। मैं समझता हूं कि मैं एकत्रीकरण ढांचे का उपयोग कर सकता हूं लेकिन ऐसा लगता है कि इस मामले में यह अधिक होगा। एकत्रीकरण ढांचा शायद एक ही खोज क्वेरी के रूप में तेज़ नहीं होगा। पाठ्यक्रम संग्रह को क्वेरी करने का कोई तरीका है ताकि लौटाया गया दस्तावेज़ इस तरह के रूप में हो सकता है?

{ 
     "_id" : ObjectId("51780fb5c9c41825e3e21fc4"), 
     "name" : "CS 101", 
     "students" : [ 
       ObjectId("51780f796ec4051a536015d0"), 
     ] 
} 

उत्तर

50

[ संपादित करें अब इस संस्करण के आधार पर हाल के संस्करणों में संभव है]

[अपडेट किया गया उत्तर] आप कक्षा का नाम वापस पाने के लिए निम्न तरीके से पूछ सकते हैं और छात्र आईडी केवल तभी हैं जब वे हैं एडी नामांकित

db.student.find({}, 
{_id:0, name:1, students:{$elemMatch:{$eq:ObjectId("51780f796ec4051a536015cf")}}}) 

और तुम वापस मिल जाएगा कि तुम क्या उम्मीद:

{ "name" : "CS 101", "students" : [ ObjectId("51780f796ec4051a536015cf") ] } 
{ "name" : "Literature" } 
{ "name" : "Physics", "students" : [ ObjectId("51780f796ec4051a536015cf") ] } 

[मूल उत्तर] यह क्या आप वर्तमान में क्या करना चाहते हैं क्या करने के लिए संभव नहीं है। यह दुर्भाग्यपूर्ण है क्योंकि यदि आप किसी ऑब्जेक्ट के रूप में सरणी में संग्रहीत किया गया था तो आप ऐसा करने में सक्षम होंगे। असल में, मैं थोड़ा आश्चर्यचकित हूं कि आप ऑब्जेक्टआईडी() का उपयोग कर रहे हैं क्योंकि हमेशा आपको छात्रों को देखने की आवश्यकता है यदि आप किसी विशेष पाठ्यक्रम में नामांकित छात्रों की एक सूची प्रदर्शित करना चाहते हैं (आईडी की पहली सूची देखें फिर छात्रों के संग्रह में नाम देखें - एक के बजाय दो प्रश्न!)

यदि आप एक उदाहरण के रूप (भंडारण किया गया) एक आईडी और इस तरह पाठ्यक्रम सरणी में नाम:

{ 
     "_id" : ObjectId("51780fb5c9c41825e3e21fc6"), 
     "name" : "Physics", 
     "students" : [ 
       {id: ObjectId("51780f796ec4051a536015cf"), name: "John"}, 
       {id: ObjectId("51780f796ec4051a536015d0"), name: "Sam"} 
     ] 
} 

आपकी क्वेरी तो बस होगा:

db.course.find({ }, 
       { students : 
        { $elemMatch : 
         { id : ObjectId("51780f796ec4051a536015d0"), 
         name : "Sam" 
         } 
        } 
       } 
); 

हैं कि छात्र था केवल सीएस 101 में नामांकित आप वापस मिलेंगे:

{ "name" : "Literature" } 
{ "name" : "Physics" } 
{ 
    "name" : "CS 101", 
    "students" : [ 
     { 
      "id" : ObjectId("51780f796ec4051a536015cf"), 
      "name" : "John" 
     } 
    ] 
} 
+0

में एकाधिक छात्र आईडी मान सूचीबद्ध कर रहे हों, सरल सरणी के साथ-साथ उप-दस्तावेज़ों के सरणी पूछने में सक्षम न होने पर मेरे विचारों की पुष्टि करने के लिए धन्यवाद। मुझे लगता है मुझे अपनी स्कीमा का फिर से मूल्यांकन करना होगा। क्या आप जानते हैं कि 10 जीन इस मुद्दे को हल करने की योजना बना रहा है या नहीं? – shargors

+0

मैं jira.mongodb.org में इसके लिए जिरा टिकट नहीं ढूंढ पाया और वहां टिकट के बिना रिलीज के लिए कुछ भी निर्धारित नहीं हुआ, इसलिए मैं निश्चित रूप से जल्द ही कभी नहीं कहूंगा। –

+0

http://stackoverflow.com/questions/8145523/mongodb-find-by-multiple-array-items – Xerri

14

ऐसा लगता है कि $in ऑपरेटर आपके उद्देश्यों को ठीक से ठीक करेगा।

आप इस (छद्म क्वेरी) की तरह कुछ कर सकता है:।

if (db.courses.find({"students" : {"$in" : [studentId]}, "course" : courseId }).count() > 0) { 
    // student is enrolled in class 
} 

वैकल्पिक रूप से, आप "course" : courseId खंड को हटाने और सभी वर्गों के छात्र में दाखिला लिया है का एक सेट वापस मिल सकता है

+0

उस दृष्टिकोण के साथ समस्या यह है कि यह पाठ्यक्रम संग्रह से एक दस्तावेज़ वापस करेगा आयन केवल तभी जब छात्र कोर्स के लिए पंजीकृत हो। यदि छात्र पंजीकृत नहीं है, तो दूसरी क्वेरी की आवश्यकता होगी। यह कुशल नहीं है। – shargors

+0

दूसरी क्वेरी छात्र की ऑब्जेक्ट आईडी पुनर्प्राप्त करने के लिए होगी? लेकिन यह पहले से ही ज्ञात नहीं होगा (आखिरकार, आप पहली क्वेरी बनाने के लिए इसका उपयोग कर रहे हैं)। – xbonez

+0

अंतिम लक्ष्य कोर्स दस्तावेज़ को पुनर्प्राप्त करना है और यह इंगित करने के लिए एक झंडा है कि छात्र इसके लिए पंजीकृत है या नहीं। आपके द्वारा प्रदान की गई क्वेरी केवल पाठ्यक्रम दस्तावेज को पुनर्प्राप्त करेगी यदि छात्र इसके लिए पंजीकृत है। यदि छात्र कोर्स के लिए पंजीकृत नहीं है तो कोर्स दस्तावेज़ पुनर्प्राप्त करने के लिए एक और क्वेरी की आवश्यकता है। – shargors

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