ElasticSearch 6.x RestHighLevelClient updateRequest map里面放list报错原因分析

最近升级了es版本到6.x,对应也使用RestHighLevelClient,在对文档进行更新时遇到一个错误:

ElasticsearchStatusException[Elasticsearch exception [type=mapper_parsing_exception, reason=object mapping for [realtimeLocus] tried to parse field [null] as object, but found a concrete value]]
at org.elasticsearch.rest.BytesRestResponse.errorFromXContent(BytesRestResponse.java:177)
at org.elasticsearch.client.RestHighLevelClient.parseEntity(RestHighLevelClient.java:618)
at org.elasticsearch.client.RestHighLevelClient.parseResponseException(RestHighLevelClient.java:594)
at org.elasticsearch.client.RestHighLevelClient.performRequest(RestHighLevelClient.java:501)
at org.elasticsearch.client.RestHighLevelClient.performRequestAndParseEntity(RestHighLevelClient.java:474)
at org.elasticsearch.client.RestHighLevelClient.update(RestHighLevelClient.java:353)

引起这个错误的代码如下:

        Map map=new HashMap<>();

       ....

        map.put("realtimeLocus", realtimeLocusList);

      .....

      UpdateRequest updateRequest = new UpdateRequest("xxx","xxx",id).doc(map);

      UpdateResponse res= client.update(updateRequest);

为什么map里面放一个list,就会有引起这个报错呢,debug下代码并跟踪到es源码,在源代码里面发现如下代码:

    public IndexRequest source(Map source, XContentType contentType) throws ElasticsearchGenerationException {
        try {
            XContentBuilder builder = XContentFactory.contentBuilder(contentType);
            builder.map(source);
            return source(builder);
        } catch (IOException e) {
            throw new ElasticsearchGenerationException("Failed to generate [" + source + "]", e);
        }

    }

可见其实es内部会用XContentBuilder将map序列化,问题就出在这里,它会序列化成什么结果呢,如下所示:

{"realtimeLocus":["Locus [latitude=32.033997388575905, longitude=116.70294452125422]","Locus [latitude=32.03397795475233, longitude=116.70300190759406]", .....}

这就造成了最终在想要保存list结果到es的时候报错,因为它将list结果序列化成string了,而不是object。

解决该问题的办法是什么呢?

就是别直接用map去做更新,而是用json去更新,自己把map序列化成json也可以。





你可能感兴趣的:(elasticsearch)