Solución:
Utilice el resultado del cursor de la agregación para recorrer los documentos con el cursor forEach()
y luego elimine cada documento de la colección usando el _id
como la consulta en el remove()
método. Algo como esto:
var cursor = db.grades.aggregate(pipeline);
cursor.forEach(function (doc){
db.grades.remove({"_id": doc._id});
});
Otro enfoque es crear una matriz de los _id
s usando el map()
método y eliminar los documentos como:
var cursor = db.grades.aggregate(pipeline),
ids = cursor.map(function (doc) { return doc._id; });
db.grades.remove({"_id": { "$in": ids }});
– ACTUALIZAR –
Para operaciones de borrado grandes, puede ser más eficiente copiar los documentos que desea conservar en una nueva colección y luego usarlos. drop()
en la colección original. Para copiar los documentos esenciales, su canal de agregación debe devolver los documentos sin el documento de tarea más bajo y copiarlos a otra colección utilizando el $out
operador como la etapa final de la tubería. Considere la siguiente canalización de agregación:
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"
}
])
en el que luego puede eliminar la colección anterior por db.grades.drop()
y luego consultar sobre db.new_grades.find()
Creo que esta es la parte de una base de datos de la tarea de MongoDB para desarrolladores de Java proporcionada por la Universidad de MongoDB. Donde el requisito es eliminar la puntuación más baja de cada estudiante individual. de todos modos lo resolví de esta manera. Espero que te sea de ayuda. También puede clonar mi código desde mi enlace de github (proporcionado a continuación)
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();
}
}
En mi cuenta de Github tengo el código completo del proyecto. Si alguien quiere, puede probar desde este enlace.
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})
})