Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Remove records from Mongodb using shell

Tags:

mongodb

I have a simple collection populated with student data and I need to remove some records based on some parameters. I executed the following from mongoshell

for(i=0;i<200;i++) {
    var rec = db.grades.find({student_id:i,type:'homework'}).sort({score:1}).limit(1)
    db.grades.remove(rec)
}

Ideally it should remove lowest score of type homework for all student_ids. Apparently, only the last 2 records (student_id: 199) from the find parameter was purged and the rest still exists.

db.grades.find({student_id:10,type:'homework'}).sort({score:1}).limit(1)
{ "_id" : ObjectId("50906d7fa3c412bb040eb5a1"), "student_id" : 10, "type" : "homework", "score" : 6.094174990746648 }

Is it because of the aysnchoronous nature of JS / Mongo ? What are the other alternatives for solving the same?

like image 433
Rahul Avatar asked Feb 03 '13 08:02

Rahul


2 Answers

rec is not a document, it is a database cursor. You need to actually get a document from it:

for(i=0;i<200;i++) {
    var cur = db.grades.find({student_id:i,type:'homework'}).sort({score:1}).limit(1);
    var actualDoc = cur.next();
    db.grades.remove(actualDoc);
}

Otherwise, you're trying to remove documents based on cursor properties, which is not what you want. See also http://docs.mongodb.org/manual/core/read-operations/#cursors.

like image 185
kristina Avatar answered Sep 18 '22 23:09

kristina


You need to query the collection and return all of the documents in the collection first before iterating through it e.g.

var collection = grades.find({'type':'homework'}).sort({'student_id',1, 'score':1})

Then iterate through the records in the variable 'collection' removing documents with the lowest score. You also have an issue assigning i as a value to student_id without assigning the documents in the collection. And according to your code you're iterating through the collection based on student id. You don't need to do this to iterate through the collection. Just query all records of type homework then remove based on parameters. If you need to assign the value of student_id to a variable (hint: as a parameter to remove records), just assign student_id to a variable like so:

var id = ['student_id']

Alternatively (and this is the way I did it), you could sort all the records first by student_id and then by score. The score should be sorted in descending order.

Then iterate through the collection using a for loop, and when the student_id changes remove the record. To recognise the change in student_id store that value in a variable outside the loop and inside the loop (as 2 separate variables) then update them as you loop through the collection. Then compare the variables and remove the record if the values of the variables are not equal.

like image 40
br3w5 Avatar answered Sep 18 '22 23:09

br3w5