JSon Response returned by ES to SearchReponse Java object


I use this code (based on my search) to convert JSon String response returned by a query issued against ES 1.3.2 to a SearchResponse object in order to navigate with the java objects (total, hits, ...)

InputStream is = new ByteArrayInputStream(result.getBytes(StandardCharsets.UTF_8));
        InputStreamStreamInput stream = new InputStreamStreamInput(is);
        SearchResponse searchResponse = SearchResponse.readSearchResponse(stream);

But I get this error

java.io.IOException: Can't read unknown type [101]
at org.elasticsearch.common.io.stream.StreamInput.readGenericValue(StreamInput.java:435)
at org.elasticsearch.common.io.stream.StreamInput.readGenericValue(StreamInput.java:411)
at org.elasticsearch.common.io.stream.StreamInput.readMap(StreamInput.java:359)
at org.elasticsearch.transport.TransportMessage.readFrom(TransportMessage.java:86)
at org.elasticsearch.action.ActionResponse.readFrom(ActionResponse.java:35)
at org.elasticsearch.action.search.SearchResponse.readFrom(SearchResponse.java:226)
at org.elasticsearch.action.search.SearchResponse.readSearchResponse(SearchResponse.java:220)

The json string (returned by ES) looks correct

"took" : 2,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"failed" : 0
"hits" : {
"total" : 1,
"max_score" : 1.0,
"hits" : [ {
"_index" : "blog",
"_type" : "post",
"_id" : "_a0wZNZwTaSlC_D2-3FPNg",
"_score" : 1.0,
"_source":{"user":"cmoulliard","postDate":"2014-12-12","body":"Integration is hard. Integration should be easy.","title":"On distributed search"}
} ]

Is there a way to map JSon String to a SearchReponse object or I should use JSONObject, JSONArray to map the result ?



Why not just use the Java API to execute the search request? You will get a SearchResponse object back directly: https://www.elastic.co/guide/en/elasticsearch/client/java-api/current/search.html

Because I'm doing a HTTP Call using an Apache Camel endpoint. We have developed a camel-elasticsearch component but the search function will only be available within the next release (camel 2.16). So with camel-elasticsearch 2.15 (= java elasticsearch client), I can't use this feature

It is always possible that I code the ES Java client within a java class that I'm calling from Camel route but as the code developed is for demo purpose, I would like to avoid that the students have too much lines of code to write :wink: during the lab.

The method you are trying to use is for deserialising the internal transport protocol to a Java Object. It's input is not JSON which is why you are having issues. There is no JSON parser for the SearchResponse object as it is created internally as a java object and serialised to JSON for the REST interface and serialised using the transport protocol for the JAVA API. I would advise you to use the Java API, you can probably abstract some of the code away for your particular use case to mean that your students having to right lots of boilerplate code. If you try to hack this to work you will probably find it is very hard to maintain as new releases of Elasticsearch are released.

On a related note, version 1.3.2 is pretty old now, if you are creating a library for Elasticsearch I would advise using a recent version.

Finally, I have developed the code using the Java ES Client API - https://github.com/gpe-mw-training/fuse-lab-emea-2015/blob/master/src/main/java/com/redhat/gpe/route/ElasticSearchService.java#L129-L154

Thx for the explanation !