Spring MongoDB Data: Accessing and Updating Additional Documents

The first experiments with Spring Data and MongoDB were great. Now I have the following structure (simplified):

public class Letter { @Id private String id; private List<Section> sections; } public class Section { private String id; private String content; } 

Downloading and saving entire objects / documents Letter works like a charm. (I use ObjectId to generate unique identifiers for the Section.id field.)

 Letter letter1 = mongoTemplate.findById(id, Letter.class) mongoTemplate.insert(letter2); mongoTemplate.save(letter3); 

Since the documents are large (200 KB), and sometimes applications only need parts: is it possible to request a subdocument (section), change and save it? I would like to implement a method like

 Section s = findLetterSection(letterId, sectionId); s.setText("blubb"); replaceLetterSection(letterId, sectionId, s); 

And, of course, methods such as:

 addLetterSection(letterId, s); // add after last section insertLetterSection(letterId, sectionId, s); // insert before given section deleteLetterSection(letterId, sectionId); // delete given section 

I see that the last three methods are somewhat "strange", i.e. downloading the entire document, changing the collection and saving it again may be the best approach from an object-oriented point of view; but the first use case (β€œtransition” to a sub-object / sub-object and working in the area of ​​this object) seems natural.

I think MongoDB can update subdocuments, but can SpringData be used to map objects? Thanks for any pointers.

+6
source share
1 answer

I calculated the following approach for slicing and loading only one subobject. Does this seem normal? I know about problems with simultaneous changes.

 Query query1 = Query.query(Criteria.where("_id").is(instance)); query1.fields().include("sections._id"); LetterInstance letter1 = mongoTemplate.findOne(query1, LetterInstance.class); LetterSection emptySection = letter1.findSectionById(sectionId); int index = letter1.getSections().indexOf(emptySection); Query query2 = Query.query(Criteria.where("_id").is(instance)); query2.fields().include("sections").slice("sections", index, 1); LetterInstance letter2 = mongoTemplate.findOne(query2, LetterInstance.class); LetterSection section = letter2.getSections().get(0); 

This is an alternative solution, loading all sections, but omitting other (large) fields.

 Query query = Query.query(Criteria.where("_id").is(instance)); query.fields().include("sections"); LetterInstance letter = mongoTemplate.findOne(query, LetterInstance.class); LetterSection section = letter.findSectionById(sectionId); 

This is the code that I use to store only one element of the collection:

 MongoConverter converter = mongoTemplate.getConverter(); DBObject newSectionRec = (DBObject)converter.convertToMongoType(newSection); Query query = Query.query(Criteria.where("_id").is(instance).and("sections._id").is(new ObjectId(newSection.getSectionId()))); Update update = new Update().set("sections.$", newSectionRec); mongoTemplate.updateFirst(query, update, LetterInstance.class); 

It's nice to see how Spring Data can be used with "partial results" from MongoDB.

Any comments are greatly appreciated!

+12
source

Source: https://habr.com/ru/post/923116/


All Articles