mongodb - 如何删除mongodb中group返回的文档?

标签 mongodb mongodb-query aggregation-framework

我是 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、score排序
3:对student_id进行分组,找到第一个元素

这将为我提供所有得分最低的文档,

但是我如何从原始数据集中删除这些元素?有什么指导或提示吗?

最佳答案

使用聚合产生的游标结果循环遍历游标forEach()的文档。方法,然后使用 _id 作为 remove() 中的查询从集合中删除每个文档。方法。像这样的事情:

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

另一种方法是使用 map() 创建文档 _id 的数组。方法并删除如下文档:

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()

关于mongodb - 如何删除mongodb中group返回的文档?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30615981/

相关文章:

node.js - 无法在 Ubuntu 18.04 Bionic 上安装/删除 mongodb-org - "mongodb-org-tools : Depends: mongodb-database-tools but it is not installed"

mongodb - 获取 MongoDB 集合中第一条插入记录的最佳方法

javascript - MongoDB - 即时从 ID 获取数据

mongodb - 聚合数组中的对象匹配多个条件的文档

node.js - 如何处理 MongoClient 中的超时错误?

javascript - 合并 MongoDB 查询

mongodb - 使用 mongodb 的多级 $group

mongodb - 计算Mongodb聚合中2个日期之间的天数

node.js - 如何监视 MongoDB 更改流中特定字段的更改

mongodb - MongoDB 文本索引的词干提取无法正常工作