简体   繁体   中英

Upsert Mongo Document using spring data mongo

I have a Class

@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;
  }
}

i have added annotated application with @EnableMongoAuditing

i have created interface which implements mongorepository

public interface MyDocumentRepository extends MongoRepository<MyDocument, String> { }

when i have created RestController with GET , POST , PATCH methods in POST I'm sending {'title':'first'}

Controller Class POST method is

@RequestMapping(value = "/", method = RequestMethod.POST)
public ResponseEntity<?> saveMyDocument(@RequestBody MyDocument myDocument) { 
   MyDocument doc = myDocumentRepo.save(myDocument);
   return new ResponseEntity<MyDocument>(doc, HttpStatus.CREATED);
}

Its saving the data in mongo.

{
    "_id" : ObjectId("56b3451f0364b03f3098f101"),
    "_class" : "com.wiziq.service.course.model.MyDocument",
    "title" : "test"
}

and PATCH request is like

@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);
}

when in make PATCH request with data {"description":"This is test"} it update the docuent BUT it removes title field and createdDate form the document, its doing update which is ok. But i wanted to do an upsert, i can do its using mongoTemplate, but there i have to set each property which i want to set.

Is there any generic way to that if i get a PATCH request i can update only not null properties.. properties which are coming in request

spring-data-rest seems to do it using @RepositoryRestResource. How can i achieve the same.

I don't want to code like this Update update = new Update().set("title", myDocument.getTitle()).set("description", myDocument.getdescription());

Unfortunately its the behavior in MongoDB, you can verify the same using shell. So to update create an Update Object and using

Query query = new Query(Criteria.where("id").is(ID)); 

Here ID is the document which you want to update.Based on your requirement set upsert after that using findAndModify update document.

mongoTemplate.findAndModify(query, update,
                new FindAndModifyOptions().returnNew(true).upsert(false),
                someclass.class);

If you have a model like MyModel.class and you need a smooth way to create an Update object from it there is no real clear way how to do this but you can use MongoConverter bean that is created in Spring Data Mongo auto configuration and then just use replaceOne method of MongoCollection.

@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));
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM