Reputation: 477
I've written the following program to update a set records by removing the lowest grade. Based on the output from the program, it appears that the UpdateResult.matchedCount=1 but the UpdateResult.ModifiedCount=0. Essentially, the query is finding the record to be updated, but is not updating the record.
public static void main(String[] args) {
MongoClient client = new MongoClient();
MongoDatabase database = client.getDatabase("school");
MongoCollection<Document> collection = database.getCollection("students");
FindIterable<Document> iterable = collection.find(new Document("scores.type", "homework")).sort(Sorts.orderBy(Sorts.ascending("_id")));
MongoCursor<Document> iterableDocument = iterable.iterator();
while (iterableDocument.hasNext()) {
Document wholeDocument = (Document) iterableDocument.next();
List<Document> scores = (List<Document>) wholeDocument.get("scores");
System.out.println("Student id: " + wholeDocument.get("_id"));
System.out.println("Student name: " + wholeDocument.get("name"));
for (final Document score1 : scores) {
for (final Document score2 : scores) {
if (score1.get("type").toString().equalsIgnoreCase("homework") && score2.get("type").toString().equalsIgnoreCase("homework")) {
Double homeworkScore1 = (Double) score1.get("score");
Double homeworkScore2 = (Double) score2.get("score");
if (homeworkScore1 < homeworkScore2) {
BasicDBList homeworkScores = new BasicDBList();
homeworkScores.add(new BasicDBObject("type", "homework").append("score", homeworkScore1));
BasicDBObject lowScoreToRemove = new BasicDBObject("scores", homeworkScores);
System.out.println("Lowest Homework score is: " + homeworkScore1);
System.out.println("Document that will be updated: " + wholeDocument);
System.out.println("Pull Document: " + new Document("$pull", lowScoreToRemove));
UpdateResult result = collection.updateOne(new Document("_id", wholeDocument.get("_id")), new BasicDBObject("$pull",
lowScoreToRemove));
System.out.println("UpdateResult: " + result + "\n");
}
}
}
}
}
iterableDocument.close();
}
Here is a sample of the output:
Student id: 199
Student name: Rae Kohout
Lowest Homework score is: 5.861613903793295
Document that will be updated: Document{{_id=199, name=Rae Kohout, scores=[Document{{type=exam, score=82.11742562118049}}, Document{{type=quiz, score=49.61295450928224}}, Document{{type=homework, score=28.86823689842918}}, Document{{type=homework, score=5.861613903793295}}]}}
Pull Document: Document{{$pull={ "scores" : [ { "type" : "homework" , "score" : 5.861613903793295}]}}}
UpdateResult: AcknowledgedUpdateResult{matchedCount=1, modifiedCount=0, upsertedId=null}
Upvotes: 1
Views: 2117
Reputation: 477
See line of code where BasicDBList is commented out.
public static void main(String[] args) {
MongoClient client = new MongoClient();
MongoDatabase database = client.getDatabase("school");
MongoCollection<Document> collection = database.getCollection("students");
FindIterable<Document> iterable = collection.find(new Document("scores.type", "homework")).sort(Sorts.orderBy(Sorts.ascending("_id")));
MongoCursor<Document> iterableDocument = iterable.iterator();
while (iterableDocument.hasNext()) {
Document wholeDocument = (Document) iterableDocument.next();
List<Document> scores = (List<Document>) wholeDocument.get("scores");
System.out.println("Student id: " + wholeDocument.get("_id"));
System.out.println("Student name: " + wholeDocument.get("name"));
for (final Document score1 : scores) {
for (final Document score2 : scores) {
if (score1.get("type").toString().equalsIgnoreCase("homework") && score2.get("type").toString().equalsIgnoreCase("homework")) {
Double homeworkScore1 = (Double) score1.get("score");
Double homeworkScore2 = (Double) score2.get("score");
if (homeworkScore1 < homeworkScore2) {
//BasicDBList homeworkScores = new BasicDBList();
//homeworkScores.add(new BasicDBObject("type", "homework").append("score", homeworkScore1));
BasicDBObject lowScoreToRemove = new BasicDBObject("scores", new BasicDBObject("type", "homework").append("score", homeworkScore1));
System.out.println("Lowest Homework score is: " + homeworkScore1);
System.out.println("Document that will be updated: " + wholeDocument);
System.out.println("Pull Document: " + new Document("$pull", lowScoreToRemove));
UpdateResult result = collection.updateOne(new Document("_id", wholeDocument.get("_id")), new BasicDBObject("$pull",
lowScoreToRemove));
//iterable.
System.out.println("UpdateResult: " + result + "\n");
}
}
}
}
}
iterableDocument.close();
}
Upvotes: 0
Reputation: 2381
My mongo version doesn't have updateOne, but at least from my experience with 'update' the parameter should not be an array.
So instead of:
{$pull:{scores:[{type:'homework', score:5.5...}]}});
it should be (note the lack of "["):
{$pull:{scores:{type:'homework', score:5.5...}}});
Regardless, note there are reported bugs/unintuitive features about WriteResult, so I suggest to also manually look at your collection to see what's been deleted.
Upvotes: 1