我是 Spring Data Mongo 的新手。我有一个场景,我想创建一个研究,如果已经不存在于mongo db中。如果它已经存在,那么我将使用新值更新它。
我尝试了以下方式,在我的情况下工作得很好,但就性能而言,我不确定这是更正等的正确/最佳/建议方式。
有人可以请指导吗?
public void saveStudy(List<Study> studies) {
for (Study study : studies) {
String id = study.getId();
Study presentInDBStudy = studyRepository.findOne(id);
//find the document, modify and update it with save() method.
if(presentInDBStudy != null) {
presentInDBStudy.setTitle(task.getTitle());
presentInDBStudy.setDescription(study.getDescription());
presentInDBStudy.setStart(study.getStart());
presentInDBStudy.setEnd(study.getEnd());
repository.save(presentInDBStudy);
}
else
repository.save(study);
}
}
答案 0 :(得分:2)
您必须使用MongoTemplate.upsert()
来实现此目的。
您需要再添加两个类:StudyRepositoryCustom
这是一个interface
和一个扩展此界面的类,比如StudyRepositoryImpl
interface StudyRepositoryCustom {
public WriteResult updateStudy(Study study);
}
将您当前的StudyRepository
更新为extend
此interface
@Repository
public interface StudyRepository extends MongoRepository<Study, String>, StudyRepositoryCustom {
// ... Your code as before
}
添加一个实现StudyRepositoryCustom
的类。这是我们@Autowire
我们MongoTemplate
的所在位置,并提供更新Study
的实施方案,或者如果不存在则保存。{1}}。我们使用MongoTemplate.upsert()
方法。
class StudyRepositoryImpl implements StudyRepositoryCustom {
@Autowired
MongoTemplate mongoTemplate;
public WriteResult updateStudy(Study study) {
Query searchQuery = new Query(Criteria.where("id").is(study.getId());
WriteResult update = mongoTemplate.upsert(searchQuery, Update.update("title", study.getTitle).set("description", study.getDescription()).set(...)), Study.class);
return update;
}
}
请注意,StudyRepositoryImpl
将自动被Spring Data基础架构选中,因为我们遵循了使用Impl
扩展核心存储库接口名称的命名约定
检查github上的this示例,@Autowire
- MongoTemplate
并使用上面的自定义存储库。
我没有测试过代码,但它会指导您: - )
答案 1 :(得分:1)
您可以使用mongo文档中描述的upsert功能。 https://ng-bootstrap.github.io/#/components/modal
答案 2 :(得分:1)
您可以更新代码以使用<S extends T> List<S> save(Iterable<S> entites);
保存所有实体。 Spring的MongoRepository
将根据_id字段及其值的存在来处理所有可能的情况。
此处提供更多信息https://docs.mongodb.com/manual/reference/method/db.collection.save/
这对基本的保存操作很有用。您不必加载文档以进行更新。只需设置id并确保通过替换现有文档来包含所有要更新的字段。
简化域对象:
@Document(collection = "study")
public class Study {
@Id
private String id;
private String name;
private String value;
}
存储库:
public interface StudyRepository extends MongoRepository<Study, String> {}
想象一下,你现有_id = 1
之前的收集状态:
{
"_id" : 1,
"_class" : "com.mongo.Study",
"name" : "saveType",
"value" : "insert"
}
运行所有可能的案例:
public void saveStudies() {
List<Study> studies = new ArrayList<Study>();
--Updates the existing record by replacing with the below values.
Study update = new Study();
update.setId(1);
update.setName("saveType");
update.setValue("update");
studies.add(update);
--Inserts a new record.
Study insert = new Study();
insert.setName("saveType");
insert.setValue("insert");
studies.add(insert);
--Upserts a record.
Study upsert = new Study();
upsert.setId(2);
upsert.setName("saveType");
upsert.setValue("upsert");
studies.add(upsert);
studyRepository.save(studies);
}
收集后状态:
{
"_id" : 1,
"_class" : "com.mongo.Study",
"name" : "saveType",
"value" : "update"
}
{
"_id" : 3,
"_class" : "com.mongo.Study",
"name" : "saveType",
"value" : "insert"
}
{
"_id" : 2,
"_class" : "com.mongo.Study",
"name" : "saveType",
"value" : "upsert"
}