首页 > 解决方案 > 使用spring java复制mongo文档的最佳方法

问题描述

我有一个具有以下结构的文档:

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

数据列表非常庞大。现在我的用例是创建一个版本 1 的新报告,其中包含版本 0 中的现有数据。

编辑:它不仅仅是更新版本。而是创建现有文档的副本。

最简单的方法是从数据库版本 0 中读取并将 id 更新为“Jan-2018-1”,然后保存。

但是由于数据列表很大,我认为阅读整个文档并不好。

所以现在,我通过避开数据字段来阅读文档,然后在更新 id 后保存报告。然后读取页面中的数据并将其附加到新版本中。

像这样的东西:

保存没有数据的新版本

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

填充数据的伪代码:

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

还有比这个更好的方法吗?使用java spring mongo。

标签: javamongodbspring-bootspring-dataspring-data-mongodb

解决方案


您可以在不获取实体的情况下创建自定义就地更新。以下是您需要采取的步骤:

1.为实体报告创建一个CustomRepository:

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

2.创建一个CustomeRepository实现:

第一次通过聚合,您将文档复制到集合中,第二次更新时,匹配操作将导致两个文档,您只需更新其中一个。

@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.从 customReportReposiotry 接口扩展您的存储库:

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

}

推荐阅读