skip to Main Content

In my application, we have mongo db for data persistence. As part of some changes, one document is modified and we are adding a new field to it. I need to write a update job in Java.
For example let’s call the document as Employee and I am adding a new field "FullName".

The update job will do the following

  1. get all the records for the document
  2. update each record for the new field
  3. call MongoRepository.saveAll method

I want to know if there is an alternative way to do it?
below is the code

var newEmployees = new ArrayList<Employee>();

employeeRepository.findAll().forEach(employee -> {
 employee.setFullName(employee.getFirstName() + " " + employee.getLastName());
 newEmployees.add(employee);
});

employeeRepository.saveAll(newEmployees);

Note – we don’t perform direct db updates through mongo shell as during prod release, the support team needs extra instructions and support for such scenarios.

2

Answers


  1. For performance reason you should consider bulkWrite. Would be similar to this (in JavaScript):

    var updates = [];
    db.employeeRepository.find().forEach(x => {    
       updates.push(
          { 
             updateOne: {
                 filter: { _id: x._id },
                 update: { $set: { FullName: employee.getFirstName() + " " + employee.getLastName() } }
             }        
          });
    })
    
    db.employeeRepository.bulkWrite(updates, { ordered: false });
    

    You should also consider updateMany with aggregation pipeline, for example like this:

    db.employeeRepository.updateMany({},[
       { $set: { FullName: { $concat: [ "$firstName", " ", "$lastName" ] } } }
    ])
    
    Login or Signup to reply.
  2. Your solution still always working great, but you should be aware of issues that can happens in case of having mass data.

    you might want to consider batch processing to handle the updates in smaller chunks. This approach can prevent memory issues and optimize database operations.

     public void updateFullNameFieldInBatch(int pageSize) {
            int pageNumber = 0;
            boolean hasNextPage = true;
    
            while (hasNextPage) {
                Page<YourEntity> page = entityRepository.findAll(PageRequest.of(pageNumber, pageSize));
                if (page.hasContent()) {
                    for (YourEntity entity : page.getContent()) {
                        String field1 = entity.getField1();
                        String field2 = entity.getField2();
    
                        // Concatenate existing fields
                        String concatenatedValue = field1 + " " + field2; // Modify this according to your concatenation logic
    
                        // Set the concatenated value to the new field
                        entity.setConcatenatedField(concatenatedValue);
                    }
    
                    // Save the updated entities in batch
                    entityRepository.saveAll(page.getContent());
    
                    pageNumber++;
                } else {
                    hasNextPage = false;
                }
            }
    
            System.out.println("Fullname persisted successfully in batch.");
        }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search