ElasticSearch - Spring 启动 - Upsert 抛出 DocumentMissingException

ElasticSearch - Spring Boot - Upsert is throwing DocumentMissingException

我正在使用 Spring Boot 和 ElasticSearch。当我尝试使用 Spring 更新插入时,如果 ElasticSearch 中没有文档,它会抛出 DocumentMissingException。当 ElasticSearch 中存在文档时,相同的代码可以正常工作。

异常堆栈跟踪:

org.springframework.data.elasticsearch.ElasticsearchException: Bulk indexing has failures. Use ElasticsearchException.getFailedDocuments() for detailed messages [{U65929AR1978SGC001748=[company/vteSxfKoRF-k4g982vissw][[company][2]] DocumentMissingException[[_doc][U65929AR1978SGC001748]: document missing], U45309AR2000PTC006288=[company/vteSxfKoRF-k4g982vissw][[company][3]] DocumentMissingException[[_doc][U45309AR2000PTC006288]: document missing],...

代码:

public <S extends Company> void saveAllCustom(Iterable<S> companies) {

    List<UpdateQuery> updateQueries = new ArrayList<UpdateQuery>();

    ObjectMapper oMapper = new ObjectMapper();

    for (S company : companies) {

        Map<String, Object> companyJsonMap = (Map<String, Object>) oMapper.convertValue(company, Map.class);
    
        Map<String, Object> paramsDocument = new HashMap<String, Object>();
        paramsDocument.put("doc", companyJsonMap);
    
        Script script = new Script(
            ScriptType.INLINE
            , "painless"
            , "if (ctx._source.dataAsOf < params.doc.dataAsOf) {ctx._source = params.doc}"
            , paramsDocument);
    
        UpdateRequest updateRequest = new UpdateRequest()
            .index("company")
            .type("_doc")
            .id(company.cin)
            .script(script) // Conditional Update
            .upsert(companyJsonMap);

        UpdateQuery updateQuery = new UpdateQueryBuilder()
            .withIndexName("company")
            .withType("_doc")
            .withId(company.cin)
            .withDoUpsert(true)
            .withClass(Company.class)
            .withUpdateRequest(updateRequest)
            .build();
    
        updateQueries.add(updateQuery);
        
    }

    elasticsearchTemplate.bulkUpdate(updateQueries);
}

但是一个类似的 upsert 命令正在使用 CURL 工作:

curl -X POST "localhost:9200/company/_doc/10001/_update" -H 'Content-Type: application/json' -d'
{
    "script": {
        "lang": "painless",
        "source": "ctx._source = params.doc",
        "params": {
            "doc": {
                "name": "XYZ LIMITED - updated",
                "cin": "10001"
            }
        }
    },
    "upsert" : {
        "name": "XYZ LIMITED - newly created",
        "cin": "10001"
    }
}'

根据我的理解,当 ElasticSearch 中没有文档时,它不应该抛出 DocumentMissingException 因为我在查询中也添加了 upsert(...)

Elasticsearch 版本: 版本:6.4.3,构建:default/tar/fe40335/2018-10-30T23:17:19.084789Z,JVM:1.8.0_191

已安装插件: None

JVM 版本: java 版本“1.8.0_191” Java(TM) SE 运行时环境(build 1.8.0_191-b12) Java HotSpot(TM) 64 位服务器 VM(内部版本 25.191-b12,混合模式)

OS 版本: 达尔文内核版本 18.5.0:3 月 11 日星期一 20:40:32 PDT 2019; root:xnu-4903.251.3~3/RELEASE_X86_64 x86_64

Spring 引导版本: 2.1.7.RELEASE

Spring 数据 ElasticSearch 版本: 3.2.0.RC2

目前 Spring Data Elasticsearch 不支持此功能。

我们在ElasticsearchTemplate的源代码中看到,使用脚本时不考虑upsert。

注意这个问题has been reported,但还没有解决。