使用 spring data mongo 插入 Mongo 文档
Posted
技术标签:
【中文标题】使用 spring data mongo 插入 Mongo 文档【英文标题】:Upsert Mongo Document using spring data mongo 【发布时间】:2016-05-15 04:51:12 【问题描述】:我有一个班级
@Document
public class MyDocument
@Id
private String id;
private String title;
private String description;
private String tagLine;
@CreatedDate
private Date createdDate;
@LastModifiedDate
private Date updatedDate;
public String getId()
return id;
public void setId(String id)
this.id = id;
public String getTitle()
return title;
public void setTitle(String title)
this.title = title;
public String getDescription()
return description;
public void setDescription(String description)
this.description = description;
public String getTagLine()
return tagLine;
public void setTagLine(String tagLine)
this.tagLine = tagLine;
我添加了带有 @EnableMongoAuditing
注释的应用程序
我已经创建了实现 mongorepository 的接口
public interface MyDocumentRepository extends MongoRepository<MyDocument, String>
当我使用 GET
,POST
,PATCH
方法创建 RestController
在POST
我正在发送
'title':'first'
Controller 类的 POST 方法是
@RequestMapping(value = "/", method = RequestMethod.POST)
public ResponseEntity<?> saveMyDocument(@RequestBody MyDocument myDocument)
MyDocument doc = myDocumentRepo.save(myDocument);
return new ResponseEntity<MyDocument>(doc, HttpStatus.CREATED);
它将数据保存在 mongo 中。
"_id" : ObjectId("56b3451f0364b03f3098f101"),
"_class" : "com.wiziq.service.course.model.MyDocument",
"title" : "test"
PATCH 请求就像
@RequestMapping(value = "/id", method = RequestMethod.PATCH)
public ResponseEntity<MyDocument> updateCourse(@PathVariable(value = "id") String id,
@RequestBody MyDocument myDocument)
myDocument.setId(id);
MyDocument doc = courseService.save(myDocument);
return ResponseEntity.ok(course);
在使用数据"description":"This is test"
发出 PATCH 请求时
它更新了文档 BUT 它从文档中删除了标题字段和 createdDate ,它进行更新是可以的。但我想做一个 upsert,我可以使用 mongoTemplate,
但是我必须设置我想要设置的每个属性。
如果我收到 PATCH 请求,是否有任何通用方法,我只能更新不为空的属性.. 请求中的属性
spring-data-rest 似乎使用@RepositoryRestResource 来做到这一点。我怎样才能做到这一点。
我不想这样编码
Update update = new Update().set("title", myDocument.getTitle()).set("description", myDocument.getdescription());
【问题讨论】:
你的 courseService.save(myDocument) 函数在做什么? 运气好吗?我一直在寻找相同问题的解决方案。 【参考方案1】:不幸的是它在 MongoDB 中的行为,您可以使用 shell 验证相同的行为。 所以要更新创建一个更新对象并使用
Query query = new Query(Criteria.where("id").is(ID));
这里的 ID 是您要更新的文档。根据您的要求设置 upsert 之后使用 findAndModify 更新文档。
mongoTemplate.findAndModify(query, update,
new FindAndModifyOptions().returnNew(true).upsert(false),
someclass.class);
【讨论】:
【参考方案2】:如果你有一个像 MyModel.class 这样的模型,并且你需要一种平滑的方法来从中创建一个更新对象,那么没有真正明确的方法来做到这一点,但是你可以使用在 Spring Data Mongo 自动配置中创建的 MongoConverter bean然后只需使用 MongoCollection 的 replaceOne 方法。
@Autowired
private MongoTemplate template;
@Autowired
private MongoConverter mongoConverter;
...
@Override
public void upsertMyModel(MyModel model)
Document documentToUpsert = new Document();
mongoConverter.write(model, documentToUpsert);
template.getCollection(collectionName).replaceOne(
Filters.eq("_id", model.getId()),
documentToUpsert,
new ReplaceOptions().upsert(true));
【讨论】:
【参考方案3】:Upsert 可以使用 BulkOperations 在 Spring 数据 mongodb 中完成。
假设有两个实体 Entity1 和 Entity2。 Entity1 有foreginId
,它是Entity2 的主要id
。两者都有一个字段title
。现在,从 entity2 到 entity1 的 upsert,我们可以这样做:
Query query = new Query(Criteria.where("foreignId").is(entity2.getId()));
Update update = new Update();
update.set("title",entity2.getTitle());
List<Pair<Query, Update>> updates = new ArrayList<Pair<Query, Update>>();
updates.add(Pair.of(query, update););
BulkOperations bulkOps = this.mongoTemplate.bulkOps(BulkMode.UNORDERED, Entity1.class);
bulkOps.upsert(updates);
bulkOps.execute();
【讨论】:
以上是关于使用 spring data mongo 插入 Mongo 文档的主要内容,如果未能解决你的问题,请参考以下文章
将Mongo查询转换为spring Mongooperations
如何使用 mongo 搜索集合并返回子文档列表(Spring-data-mongo)
使用 Spring data mongo 和 Spring data elasticsearch 时如何建模?
使用 mongoTemplate 在 spring-data-mongo Java 中进行 Mongo 聚合查询