In the previous post, we discuss own we change from using mongorepository to using directly mongodb method to access and modify directly the object in db.
In this posts we look at code that was deleting with mongorepository and change it to use directly mongodb method with MongoTemplate.
Using MongoTemplate is faster and less likely to have error due to concurrency.
Here a example of the code original code with mongorepository:
@Autowired
private MongoContentRepository mongoContentRepository;
private void removeStudentFromSchool(final Student student) {
Optional<School> optionalSchool = mongoContentRepository.findById(student.getSchoolId());
if (optionalSchool.isPresent()) {
School school = optionalSchool.get();
List<Student> students = school.getStudents();
if (students != null && !students.isEmpty()) {
Optional<Student> optionalStudent = getStudentInSchool(students, student);
optionalStudent.ifPresent(studentInDb -> students.remove(studentInDb));
school.setStudents(students);
mongoContentRepository.save(school);
}
}
}
To do the same thing by calling the mongodb operator pull with MongoTemplate
Source: https://docs.mongodb.com/manual/reference/operator/update/pull/
Doing a pull directly in a mongodb query work like this:
db.getCollection('contentDetails').update(
{_id : "1000102088"},
{$pull: { "students": {_id : "1000102183", name: "John Smith"}}},
{multi: true}
)
In Java it’s translate to this:
public void removeStudentInSchool(String schoolId, Student student) {
mongoTemplate.updateFirst(
Query.query(Criteria.where(CRITERIA_ID).is(schoolId)),
new Update().pull("student", Query.query(Criteria.where(CRITERIA_ID).is(student.getId()))), COLLECTION_NAME);
}
So if we change the original code to use Mongo template it look like this:
public void removeStudentInSchool(String schoolId, Student student) {
mongoTemplate.updateFirst(
Query.query(Criteria.where(CRITERIA_ID).is(schoolId)),
new Update().pull("student", Query.query(Criteria.where(CRITERIA_ID).is(student.getId()))), COLLECTION_NAME);
}
private void removeStudentToSchool(final Student student) {
Optional<School> optionalSchool = mongoContentRepository.findById(student.getSchoolId());
if (optionalSchool.isPresent()) {
School school = optionalSchool.get();
List<Student> students = school.getStudents();
if (students != null && !students.isEmpty()) {
Optional<Student> optionalStudent = getStudentInSchool(students, student);
optionalStudent.ifPresentOrElse(studentInDb -> contentCollection.removeStudentInSchool(studentInDb.getId(), details),
() -> log.debug("{} already remove from school {}",student.getName(), school.getName()));
}
}
Like updating in mongodb removing with the $pull operator is atomic, so it solved the concurency problem.
More on the same subject :
https://stackoverflow.com/questions/16959099/how-to-remove-array-element-in-mongodb
https://docs.mongodb.com/manual/reference/operator/update/pull/
https://stackoverflow.com/questions/40292201/mongodb-pull-using-java-driver
Recent Comments