1

I have a document having the following structure:

report {
    _id : "Jan-2018-0" // (Month-Year-Version)
    month : "Jan",
    year : 2018,
    version : 0,
    data : [......]
}

The list of data is really huge. Now my use case is to create a new report with version 1 which consists of the existing data in version 0.

EDIT : Its not just updating version. Its creating a duplicate of the existing document rather.

The easiest way is to read from db version 0 and update the id as "Jan-2018-1" and then save.

But since the list of data is huge, I think it is not good to read the entire document.

So for now, I'm reading the document by avoiding the data field and then save the report after updating the id. And then read the data in pages and and append it to new version.

Something like this:

To save the new version without data

Report report = reportRepository.findReport("Jan", 2018, 0); // ignores data field
report.setId("Jan-2018-1");
report.setVersion(1);
reportRepository.save(report);

Pseudo code to populate data:

List<Data> datas = reportRepository.getDataByPages("Jan", 2018, 0, 0//offset, 100 //limit);
reportRepository.addData("Jan", 2018, 1, datas);

Is there any other better approaches than this one? Using java spring mongo.

Kency Kurian
  • 182
  • 2
  • 11

1 Answers1

0

You can create a custom in-place update without fetching your entity.Here is the steps you need to take:

1. Create A CustomRepository for Entity Report:

public interface CustomReportRepository{
    public void updateVersionByYearAndMonth(Integer year,String month, Integer version)
}

2.Create A CustomeRepository implementation:

1st by aggregation, you copy your document to the collection, 2nd when updating, the matching operation will result in two documents where you only need to update one them.

@Repository
public class CustomReportRepositoryImpl implements CustomReportRepository {
    @Autowired
    private MongoTemplate mongoTemplate;


    @Override
    public void updateDocumentTitle(Integer year, String month, Integer version) {

        MatchOperation matchOperation =
            match(new Criteria().andOperator(
                Criteria.where("year").is(year),
                Criteria.where("month").is(month)
            ));

        Aggregation aggregation = newAggregation(matchOperation, out("yourCollectionName"));
        //copy document by aggregation
        mongoTemplate.aggregate(aggregation, "yourCollectionName", Report.class);


        Query query = new Query();
        query.addCriteria(
            new Criteria().andOperator(
                Criteria.where("year").is(year),
                Criteria.where("month").is(month)
            )
        );
        Update update = new Update();
        update.set("version", version);
        //apply update to first
        mongoTemplate.update(Report.class).matching(query).apply(update).first();

    }
}

3.extend your repository from customReportReposiotry interface:

public interface ReportRepository extends MongoRepository < Report, String > , CustomReportRepository {
    public void updateVersionByYearAndMonth(Integer year, String month, Integer version)

}
  • But this will update the existing document rt? Will it create a copy of the existing document? – Kency Kurian Sep 06 '18 at 12:31
  • Hmm... had not known about the out method. Thanks... But there is still one bit of a problem left, with this the _id will be auto generated rt? But I would like to have it as Jan-2018-1 for the new one. This is because there could be more than one thread doing the same operation. If the _id could be set by us manually, it would be perfect. I'll check the out method now. – Kency Kurian Sep 07 '18 at 07:17
  • Hope it helped. if current issue is solved, it’s a better practice to close it and separate it from other issues by raising another question as your new issue could be shared with others with another topic – MohammadReza Alagheband Sep 07 '18 at 10:01
  • 1
    No it does not solve : 1. Since it does not allow you to specify the _id as mentioned in the question. 2. Moreover I tried the same aggregation operation in mongo console and it does not copy the document. – Kency Kurian Sep 07 '18 at 11:03