6

我有一个包含学生数据的简单集合,我需要根据一些参数删除一些记录。我从 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)
}

理想情况下,它应该删除所有 student_ids 类型作业的最低分数。显然,只有 find 参数中的最后 2 条记录(student_id:199)被清除,其余的仍然存在。

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

是因为 JS / Mongo 的异步特性吗?解决相同问题的其他替代方法是什么?

4

3 回答 3

9

rec不是文档,是数据库游标。您实际上需要从中获取文档:

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);
}

否则,您将尝试根据光标属性删除文档,这不是您想要的。另请参阅http://docs.mongodb.org/manual/core/read-operations/#cursors

于 2013-02-06T03:58:17.483 回答
1

您需要先查询集合并返回集合中的所有文档,然后再遍历它,例如

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

然后遍历变量“集合”中的记录,删除得分最低的文档。您也有一个问题,将 i 作为值分配给 student_id 而不分配集合中的文档。根据您的代码,您正在根据学生 ID 遍历集合。您无需执行此操作即可遍历集合。只需查询所有作业类型的记录,然后根据参数删除。如果您需要将 student_id 的值分配给一个变量(提示:作为删除记录的参数),只需将 student_id 分配给一个变量,如下所示:

var id = ['student_id']

或者(这就是我这样做的方式),您可以先按 student_id 对所有记录进行排序,然后按分数排序。分数应按降序排列。

然后使用 for 循环遍历集合,并在 student_id 更改时删除记录。要识别 student_id 的变化,将该值存储在循环外和循环内的变量中(作为 2 个单独的变量),然后在循环遍历集合时更新它们。然后比较变量,如果变量的值不相等,则删除记录。

于 2013-02-03T08:39:55.783 回答
0
var oldid=-1;
var cursor=db.grades.find({'type':'homework'}).sort({'student_id':1,'score':1});
while (cursor.hasNext()) { 
    var doc = cursor.next(); 
    var id = doc['student_id']; 
    if (oldid!=id) 
    {
        db.grades.remove(doc);
        oldid=id; 
    } 
 }
于 2014-09-19T02:05:29.187 回答