2015-06-03 18 views
7

मैं MongoDB शुरुआत कर रहा हूँ और एक होमवर्क समस्या पर काम कर रहा हूँ, डाटासेट इसmongodb में समूह द्वारा लौटाए गए दस्तावेज़ों को कैसे हटाएं?

{ "_id" : { "$oid" : "50906d7fa3c412bb040eb577" }, "student_id" : 0, "type" : "exam", "score" : 54.6535436362647 } 
{ "_id" : { "$oid" : "50906d7fa3c412bb040eb578" }, "student_id" : 0, "type" : "quiz", "score" : 31.95004496742112 } 
{ "_id" : { "$oid" : "50906d7fa3c412bb040eb579" }, "student_id" : 0, "type" : "homework", "score" : 14.8504576811645 } 
{ "_id" : { "$oid" : "50906d7fa3c412bb040eb57a" }, "student_id" : 0, "type" : "homework", "score" : 63.98402553675503 } 
{ "_id" : { "$oid" : "50906d7fa3c412bb040eb57b" }, "student_id" : 1, "type" : "exam", "score" : 74.20010837299897 } 
{ "_id" : { "$oid" : "50906d7fa3c412bb040eb57c" }, "student_id" : 1, "type" : "quiz", "score" : 96.76851542258362 } 
{ "_id" : { "$oid" : "50906d7fa3c412bb040eb57d" }, "student_id" : 1, "type" : "homework", "score" : 21.33260810416115 } 
{ "_id" : { "$oid" : "50906d7fa3c412bb040eb57e" }, "student_id" : 1, "type" : "homework", "score" : 44.31667452616328 } 

की तरह दिखता है समस्या मैं प्रत्येक छात्र के लिए हटाना होगा के रूप में, सबसे कम स्कोर के साथ 'होमवर्क' दस्तावेज़। यहाँ मेरी रणनीति

कुल पाइपलाइन में है
1: पहले प्रकार के साथ सभी दस्तावेजों को फ़िल्टर: homeworks
2: student_id द्वारा क्रमबद्ध करें, स्कोर
3:, पहला तत्व student_id पर एक समूह ऐसा लगता है

यह मुझे सबसे कम स्कोर के साथ सभी दस्तावेज देगा,

हालांकि मैं इन तत्वों को मूल डेटासेट से कैसे हटा सकता हूं? कोई मार्गदर्शन या संकेत?

+0

'.remove ({})', जहां '{}' छँटाई की condtions शामिल हैं। – MegaMind

+0

संभावित डुप्लिकेट [समूह के लिए मोंगोडब में न्यूनतम मूल्य कैसे हटाएं?] (Http://stackoverflow.com/questions/13298635/how-remove-min-value-in-mongodb-for-group) – Yogesh

+0

दोस्त, यह होमवर्क लगता है परिचित। यदि आप यह नहीं समझ सकते कि इसे कैसे किया जाए, तो आपको यहां पूछने के बजाय पाठ वीडियो पर वापस जाना चाहिए। उस बुनियादी ज्ञान के बिना, आप आने वाले हफ्तों में फंस जाएंगे। –

उत्तर

13

कर्सर के forEach() विधि के साथ दस्तावेजों के माध्यम से पाश के एकत्रीकरण से कर्सर परिणाम का उपयोग करें और फिर remove() विधि में प्रश्न के रूप में _id का उपयोग कर संग्रह से प्रत्येक दस्तावेज़ को हटा दें। कुछ इस तरह:

var cursor = db.grades.aggregate(pipeline); 
cursor.forEach(function (doc){ 
    db.grades.remove({"_id": doc._id}); 
}); 

एक और दृष्टिकोण दस्तावेज के _idmap() पद्धति का उपयोग करके रों की एक सरणी बना सकते हैं और जैसे दस्तावेज़ निकालने के लिए है: - अद्यतन

var cursor = db.grades.aggregate(pipeline), 
    ids = cursor.map(function (doc) { return doc._id; }); 
db.grades.remove({"_id": { "$in": ids }}); 

-

बड़े विलोपन संचालन के लिए, उन दस्तावेजों की प्रतिलिपि बनाना अधिक कुशल हो सकता है जिन्हें आप चाहते हैं एक नए संग्रह के लिए एपी और फिर मूल संग्रह पर drop() का उपयोग करें। आवश्यक दस्तावेजों की प्रतिलिपि बनाने के लिए आपकी एकत्रीकरण पाइपलाइन को निम्नतम होमवर्क दस्तावेज़ के बिना दस्तावेज़ों को वापस करने की आवश्यकता है और $out ऑपरेटर का उपयोग करके अंतिम पाइपलाइन चरण के रूप में उन्हें किसी अन्य संग्रह में कॉपी करना होगा। निम्नलिखित एकत्रीकरण पाइपलाइन पर विचार करें:

db.grades.aggregate([  
    { 
     '$group':{ 
      '_id': { 
       "student_id": "$student_id", 
       "type": "$type" 
      }, 
      'lowest_score': { "$min": '$score'}, 
      'data': { 
       '$push': '$$ROOT' 
      } 
     } 
    },  
    { 
     "$unwind": "$data" 
    }, 
    { 
     "$project": { 
      "_id": "$data._id", 
      "student_id" : "$data.student_id", 
      "type" : "$data.type", 
      "score" : "$data.score", 
      'lowest_score': 1,    
      "isHomeworkLowest": { 
       "$cond": [ 
        { 
         "$and": [ 
          { "$eq": [ "$_id.type", "homework" ] }, 
          { "$eq": [ "$data.score", "$lowest_score" ] } 
         ] 
        }, 
        true, 
        false 
       ] 
      } 
     } 
    }, 
    { 
     "$match": {"isHomeworkLowest" : false} 
    }, 
    { 
     "$project": {   
      "student_id": 1, 
      "type": 1, 
      "score": 1 
     } 
    }, 
    { 
     "$out": "new_grades" 
    } 
]) 

जिसमें आप तो db.grades.drop() द्वारा वर्ष संग्रह ड्रॉप कर सकते हैं और फिर db.new_grades.find()

+0

क्या यह करने के लिए यह सबसे प्रभावी तरीका है? मैं पूछ रहा हूं क्योंकि मैंने अभी सीखना शुरू कर दिया है। मैंने सोचा कि एक तरीका होगा जहां एक प्रश्न में खोज/हटाना किया जा सकता है? – Dude

+0

@Dude बड़े विलोपन संचालन के लिए, उन दस्तावेज़ों की प्रतिलिपि बनाने के लिए और अधिक कुशल हो सकता है जिन्हें आप नए संग्रह में रखना चाहते हैं और फिर मूल संग्रह पर ड्रॉप() का उपयोग करें। – chridam

2

पर क्वेरी मुझे लगता है कि यह जावा डेवलपर्स के लिए MongoDB के होमवर्क के एक डेटाबेस हिस्सा द्वारा प्रदान की है मोंगो डीबी विश्वविद्यालय। जहां प्रत्येक छात्र से निम्नतम स्कोर को हटाना आवश्यक है। वैसे भी मैंने इस तरह हल किया। मुझे आशा है कि यह आपके लिए सहायक होगा। तुम भी मेरी GitHub लिंक (नीचे प्रदान की)

public class Homework2Week2 { 

public static void main(String[] args) { 
    // TODO Auto-generated method stub 
    // Here the the documentation is used for mongo-jva-driver-3.2.2.jar 
    /*If you want to use different versionof mongo-jva-driver 
     then you have look for that version specificatios.*/ 
    MongoClient mongoClient = new MongoClient(); 
    // get handle to "students" database 
    MongoDatabase database = mongoClient.getDatabase("students"); 
    // get a handle to the "grades" collection 
    MongoCollection<Document> collection = database.getCollection("grades"); 
    /* 
    * Write a program in the language of your choice that will remove the grade of type "homework" with the lowest score for each student from the dataset in the handout. 
    * Since each document is one grade, it should remove one document per student. 
    * This will use the same data set as the last problem, but if you don't have it, you can download and re-import. 
    * The dataset contains 4 scores each for 200 students. 
    * First, letâs confirm your data is intact; the number of documents should be 800. 

    *Hint/spoiler: If you select homework grade-documents, sort by student 
     and then by score, you can iterate through and find the lowest score 
     for each student by noticing a change in student id. As you notice 
     that change of student_id, remove the document. 
    */ 
    MongoCursor<Document> cursor = collection.find(eq("type", "homework")).sort(new Document("student_id", 1).append("score", 1)).iterator(); 
    int curStudentId = -1; 
    try 
    { 
    while (cursor.hasNext()) { 
     Document doc = cursor.next(); 
     int studentId=(int) doc.get("student_id"); 
     if (studentId != curStudentId) { 
      collection.deleteMany(doc); 
      curStudentId = studentId; 
     } 
    } 
    }finally { 
     //Close cursor 
     cursor.close(); 
    } 
    //Close mongoClient 
    mongoClient.close(); 
} 

}

से मेरे कोड क्लोन कर सकते हैं मेरी Github खाते में मैं पूरी परियोजना कोड है। अगर कोई चाहता है तो आप इस link से कोशिश कर सकते हैं।

+0

आप इस int studentId = Integer.valueOf (doc.get ("student_id")। ToString()) का पालन कर सकते हैं; इस int studentId = (int) doc.get ("student_id") के बजाय; –

0

int studentId = (int) doc.get ("student_id");

एक कन्वर्ट प्रकार त्रुटि देता है। क्या आप फिर से जांच सकते हैं?

जैसा कि मुझे पता है कि हम नीचे के रूप में बना सकते हैं।

int studentId = Integer.valueOf (doc.get ("student_id")। ToString());

+0

मेरे लिए, int studentId = (int) doc.get ("student_id"); काम कर रहा था। आपका भी सही है जिसका आप उपयोग कर सकते हैं। क्या आप मुझे त्रुटि लिख सकते हैं तो मैं समझूंगा कि वास्तव में क्या हो रहा है? –

1
db.grades.aggregate([ 
          { 
           $match:{type:'homework'} 
          }, 
          { $group: 
           { _id: {student_id:"$student_id",type:'$type'},         
            score: { $max: "$score" } 
           } 
          } 
          ]).forEach(function(doc){ 
db.grades.remove({'student_id':doc._id.student_id,'score':doc.score}) 

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