弹性搜索 - Spring Boot - Upsert 抛出 DocumentMissingException

7

我正在使用Spring Boot和ElasticSearch。当我尝试使用Spring进行upsert时,如果ElasticSearch中没有文档,则会抛出DocumentMissingException异常。当ElasticSearch中存在文档时,相同的代码可以正常工作。

异常堆栈跟踪:

org.springframework.data.elasticsearch.ElasticsearchException: 批量索引失败。 请使用ElasticsearchException.getFailedDocuments()获取详细信息[{U65929AR1978SGC001748=[company/vteSxfKoRF-k4g982vissw][[company][2]] DocumentMissingException[[_doc][U65929AR1978SGC001748]: 缺少文档], U45309AR2000PTC006288=[company/vteSxfKoRF-k4g982vissw][[company][3]] DocumentMissingException[[_doc][U45309AR2000PTC006288]: 缺少文档],...

代码:

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

但是使用CURL命令可以实现类似的upsert操作:
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中没有文档存在时,如果查询中加入了upsert(...),它不应该抛出DocumentMissingException异常。 Elasticsearch版本:Version: 6.4.3, Build: default/tar/fe40335/2018-10-30T23:17:19.084789Z, JVM: 1.8.0_191 已安装的插件:JVM版本:java version "1.8.0_191" Java(TM) SE Runtime Environment (build 1.8.0_191-b12) Java HotSpot(TM) 64-Bit Server VM (build 25.191-b12, mixed mode) 操作系统版本:Darwin Kernel Version 18.5.0: Mon Mar 11 20:40:32 PDT 2019; root:xnu-4903.251.3~3/RELEASE_X86_64 x86_64 Spring Boot 版本:2.1.7.RELEASE Spring Data ElasticSearch 版本:3.2.0.RC2

你正在使用哪个版本的Elasticsearch? - andrewdleach
最好在Github上有一个小的重现程序来进行彻底的调查。 - ozkanpakdil
你能否同时添加你正在使用的Spring Boot和Spring Data ES版本? - Val
@Val 在问题中添加了 Spring Boot 和 Spring Data ElasticSearch 版本。 - Amit
1个回答

8

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

我们可以在ElasticsearchTemplate的源代码中看到,当使用脚本时,并没有考虑 upsert 操作。

请注意,这个问题已经被报告过了,但目前还没有解决。


我不是在谈论那个问题。由于这是一个Spring Data ES的问题,而不是Elasticsearch的问题,所以您不应将其提交到elastic存储库中。 - Val

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接