Search code examples
javaelasticsearchspring-data-elasticsearchresthighlevelclient

Avoiding conflicts with elastic upsert


I am having an issue trying to implement optimistic locking when executing a document upsert.

I followed all the guides, however I am getting the following error:

Validation Failed: 1: compare and write operations can not be used with upsert;

I can trace this error back to this validate method, however I cannot find an explanation as to why this cannot be done nor HOW to do an upsert without running into conflicts.

Here's where I am getting the error in my code:

private UpdateResponse doAction(UUID esId, List<Comment> comments, dSeqNoPrimaryTerm seqPrimNo, String indexName) {
        UpdateResponse response = null;
        Map<String, Object> params = new HashMap<>();
        params.put("comments", comments);
        Builder builder = UpdateQuery
                .builder(esId.toString())
                .withDocAsUpsert(true)
                .withDocument(Document.from(params))
                .withRefresh(Refresh.True);
        if (seqPrimNo != null) {
            builder.withIfSeqNo((int) seqPrimNo.getSequenceNumber());
            builder.withIfPrimaryTerm((int) seqPrimNo.getPrimaryTerm());
        }
        UpdateQuery query = builder.build();
        response = elasticsearchTemplate.update(query, IndexCoordinates.of(indexName));  // <-- ERRORS HERE
        return response;
    }

Does that mean that we cannot do optimistic locking when doing an upsert? What am I missing?


Solution

  • I ended up using the latest version of Spring and did the following:

    Builder b = UpdateQuery.builder(id)
                           .withDocument(Map.of("field 1","value 1"))
                           .withRefreshPolicy(...)
                           ...
    
    // check seq no and some other stuff
    
    UpdateQuery uq = b.build();
    
    // run client and get response