我有一个具有以下结构的文件:
report {
_id : "Jan-2018-0" // (Month-Year-Version)
month : "Jan",
year : 2018,
version : 0,
data : [......]
}
数据列表真的很大。现在我的用例是使用版本1创建一个新报告,该报告由版本0中的现有数据组成。
编辑:它不只是更新版本。它创建了现有文档的副本。
最简单的方法是从db版本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。
您可以在不提取实体的情况下创建自定义就地更新。这是您需要采取的步骤:
public interface CustomReportRepository{
public void updateVersionByYearAndMonth(Integer year,String month, Integer version)
}
首先通过聚合,将文档复制到集合,更新时为第2,匹配操作将生成两个文档,您只需要更新它们。
@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();
}
}
public interface ReportRepository extends MongoRepository < Report, String > , CustomReportRepository {
public void updateVersionByYearAndMonth(Integer year, String month, Integer version)
}