spring-data-elasticsearch and update

安稳与你 提交于 2020-06-12 20:35:14

问题


i'm using spring-data-elasticsearch to do CRUD operations.

I have a custom Repository that extends ElasticsearchRepository.

Ultimately ElasticsearchRepository extends CrudRepository which implies updating an existing record is possible.

The question is, how do you accomplish this? I haven't found a method called "update()"

I thought doing the following would work (code stolen from https://github.com/BioMedCentralLtd/spring-data-elasticsearch-sample-application)

    //create
    Book book = new Book();
    book.setId("123455");
    book.setName("Spring Data Elasticsearch");
    book.setVersion(System.currentTimeMillis());
    repository.save(book);

    //update
    book.setName("THIS IS A COMPLETELY NEW TITLE");
    repository.save(book); 

However the 2nd save throws an InvocationTargetException

Examining it with the debugger shows:

[book][0] [book][123455]: version conflict, current [1447792071681], provided [1447792071681]

The Book object looks like:

@Document(indexName = "book",type = "book" , shards = 1, replicas = 0, indexStoreType = "memory", refreshInterval = "-1")
public class Book {

    @Id
    private String id;
    private String name;
    private Long price;
    @Version
    private Long version;

    public Map<Integer, Collection<String>> getBuckets() {
        return buckets;
    }

    public void setBuckets(Map<Integer, Collection<String>> buckets) {
        this.buckets = buckets;
    }

    @Field(type = FieldType.Nested)
    private Map<Integer, Collection<String>> buckets = new HashMap();

    public Book(){}

    public Book(String id, String name,Long version) {
        this.id = id;
        this.name = name;
        this.version = version;
    }

    getters and setters removed for space

}

My Repository code is even simpler:

import org.springframework.data.elasticsearch.entities.Book;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;

public interface BookRepository extends ElasticsearchRepository<Book, Long> {

}

Do I have to provide an update method?

EDIT:

Nevermind. I changed the update to:

    //update
    book.setName("THIS IS A COMPLETELY NEW TITLE");
    book.setVersion(System.currentTimeMillis());
    repository.save(book); 

and it updated the record.


回答1:


You can use UpdateQuery and ElasticSearchTemplate to update any partial document. e.g

    final UpdateRequest updateRequest = new UpdateRequest();
    updateRequest.index(mainIndexName);
    updateRequest.type(typeName);
    updateRequest.id(id);
    updateRequest.doc(XContentFactory.jsonBuilder().startObject()
                        .field("accountType", accountType)
                        .endObject());
    final UpdateQuery updateQuery = new UpdateQueryBuilder().withId(id)
                        .withClass(<DocumentClass>).withUpdateRequest(updateRequest).build();
    UpdateResponse updateResponse =  elasticSearchTemplate.update(updateQuery);



回答2:


I updated indexed document as follows code snippet:

        IndexRequest indexRequest = new IndexRequest(INDEX_NAME,INDEX_NAME,docid);
        indexRequest.source(fldName, fldValue);
        UpdateRequest updateRequest = new UpdateRequest();
        updateRequest.index(INDEX_NAME);
        updateRequest.type(INDEX_NAME);
        updateRequest.id(docid);
        updateRequest.doc(indexRequest);
        try {
            UpdateResponse res=client.update(updateRequest).get();
            logger.info("update es {}:{}",fe,res.getGetResult());
        } catch (Exception e) {
            logger.error("update",e);
            throw e;
        }



回答3:


The second update fails because you're trying to update an entity whose version hasn't changed. The error message you're getting is ES telling you, "hey, you can't save the same version twice!" Try this:

//create
Book book = new Book();
book.setId("123455");
book.setName("Spring Data Elasticsearch");
book.setVersion(System.currentTimeMillis());
repository.save(book);

//update
book.setName("THIS IS A COMPLETELY NEW TITLE");
book.setVersion(System.currentTimeMillis()); // you're saving a new version
repository.save(book); 



回答4:


I think the ElasticSearch is a similar to the JSON storage:

if(exist) {
    update it;// push json to cover it
} else {
    add it;// new save();
}

It will update the JSON when Id/Entity is exist, or it will add it.




回答5:


 XContentType contentType = 
org.elasticsearch.client.Requests.INDEX_CONTENT_TYPE;
public XContentBuilder getBuilder(User assign){
 try {
    XContentBuilder builder = XContentFactory.contentBuilder(contentType);
     builder.startObject();
     Map<String,?> assignMap=objectMap.convertValue(assign, Map.class);
              builder.field("assignee",assignMap);
     return builder;
    } catch (IOException e) {
            log.error("custom field index",e);
 }
  IndexRequest indexRequest = new IndexRequest();
    indexRequest.source(getBuilder(assign));
    UpdateQuery updateQuery = new UpdateQueryBuilder()
                                    .withType(<IndexType>)
                                    .withIndexName(<IndexName>)
                                    .withId(String.valueOf(id))
                                    .withClass(<IndexClass>)
                                    .withIndexRequest(indexRequest)
                                    .build();


来源:https://stackoverflow.com/questions/33766485/spring-data-elasticsearch-and-update

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!