Dud*_*ude 11 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 }
Run Code Online (Sandbox Code Playgroud)
作为问题的一部分,我必须为每个学生删除分数最低的"家庭作业"文档.这是我的策略
在聚合管道
1中:首先过滤所有类型的文档:homeworks
2:按student_id排序,得分
3:在student_id上做一个组,找到第一个元素
这将给我所有得分最低的文件,
但是我如何从原始数据集中删除这些元素?任何指导或提示?
chr*_*dam 23
使用聚合中的游标结果使用游标forEach()方法循环遍历文档,然后使用方法中_id的查询从集合中删除每个文档remove().像这样的东西:
var cursor = db.grades.aggregate(pipeline);
cursor.forEach(function (doc){
db.grades.remove({"_id": doc._id});
});
Run Code Online (Sandbox Code Playgroud)
另一种方法是_id使用该map()方法创建文档的数组,并删除以下文档:
var cursor = db.grades.aggregate(pipeline),
ids = cursor.map(function (doc) { return doc._id; });
db.grades.remove({"_id": { "$in": ids }});
Run Code Online (Sandbox Code Playgroud)
- 更新 -
对于大型删除操作,将要保留的文档复制到新集合然后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"
}
])
Run Code Online (Sandbox Code Playgroud)
然后,您可以在其中删除旧集合db.grades.drop(),然后查询db.new_grades.find()
我认为这是MongoDB大学提供的MongoDB for Java Developers的家庭作业的数据库部分.要求是删除每个学生的最低分.无论如何,我这样解决了.我希望它对你有所帮助.你也可以从我的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();
}
Run Code Online (Sandbox Code Playgroud)
}
在我的Github帐户中,我有完整的项目代码.如果有人想要你可以试试这个链接.
小智 5
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})
})
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
11120 次 |
| 最近记录: |