Search code examples
javaelasticsearchelastic-stackrest-client

ElasticSearch RestClient response to ResponseHits API instead of Response API not working


Am fetching documents from elasticsearch via RestClient Java API and trying to get the response in ResponseHits, so that am able to handle multiple documents (in response) using below code.

SearchHit[] contentSearchHits = contentSearchResponse.getHits().getHits();

But am not able to set the RestClient response in ResponseHits API. From Eclipse am getting this message Type mismatch: cannot convert from Response to ResponseHits.

If i use RestHighLevelClient am able to use ResponseHits class and everything goes good. But am not using it, due to BUFFER_SIZE limitation to 100MB by default, where i need more BUFFER_SIZE.

So, is there anyway to handle RestClient response if it is returning multiple doucments while searching.

Please find my Java Code that am using to fetching documents from ElasticSearch.

private final static String ATTACHMENT = "document_attachment";
    private final static String TYPE = "doc";
    static long BUFFER_SIZE = 520 * 1024 * 1024;   //  <---- set buffer to 520MB instead of 100MB


    public static void main(String args[])
    {
        RestClient restClient = null;
        Response contentSearchResponse=null;
        String responseBody = null;
        JSONObject source = null;
        String path = null;
        String filename = null;
        int id = 0;
        ResponseHits responseHits = null;

        RestClientBuilder builder =  null; 

        try {

        restClient = RestClient.builder(
                        new HttpHost("localhost", 9200, "http"),
                        new HttpHost("localhost", 9201, "http")).build();

        } catch (Exception e) {
            System.out.println(e.getMessage());
        }

        SearchRequest contentSearchRequest = new SearchRequest(ATTACHMENT); 
        SearchSourceBuilder contentSearchSourceBuilder = new SearchSourceBuilder();
        contentSearchRequest.types(TYPE);
        QueryBuilder attachmentQB = QueryBuilders.matchQuery("attachment.content", "activa");
        contentSearchSourceBuilder.query(attachmentQB);
        contentSearchSourceBuilder.size(50);
        contentSearchRequest.source(contentSearchSourceBuilder);

        Map<String, String> params = Collections.emptyMap();
        HttpEntity entity = new NStringEntity(contentSearchSourceBuilder.toString(), ContentType.APPLICATION_JSON);
        HttpAsyncResponseConsumerFactory.HeapBufferedResponseConsumerFactory consumerFactory =
                new HttpAsyncResponseConsumerFactory.HeapBufferedResponseConsumerFactory((int) BUFFER_SIZE);


        try {
            //contentSearchResponse = restClient.performRequest("GET", "/document_attachment/doc/_search", params, entity, consumerFactory); //  this is working with single document, not sure how to handle if request is returning multiple documents while searching.
            responseHits  = restClient.performRequest("GET", "/document_attachment/doc/_search", params, entity, consumerFactory); // am not able to set the response to `ResponseHits` class
        } catch (IOException e1) {
            e1.printStackTrace();
        } 

        try {
            responseBody = EntityUtils.toString(contentSearchResponse.getEntity());
        } catch (ParseException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        System.out.println("Converting to JSON");
        JSONObject jsonObject = new JSONObject(responseBody);
        JSONObject  hits = jsonObject.getJSONObject("hits");
        JSONArray hitsArray=hits.getJSONArray("hits");
        for(int i=0;i<hitsArray.length();i++) {
            JSONObject obj= hitsArray.getJSONObject(i);
            source = obj.getJSONObject("_source");
            id = Integer.parseInt(source.opt("id").toString());
            path = source.optString("path");
            filename = source.optString("filename");

        }

        JSONObject jsonBody = new JSONObject();
        jsonBody.put("id", id);
        jsonBody.put("path", path);
        jsonBody.put("filename", filename);
        System.out.println("Response --->"+jsonBody.toString());

        }

Am using ElasticSearch Version 6.2.3


Solution

  • I have found the way to handle multiple documents from RestClient response

                 JSONArray hitsArray;
                 JSONArray responseArray = new JSONArray();
                 JSONObject responseObj;
                 String fileRelativePath=null;
    
                 JSONObject json = new JSONObject(responseBody);
                 JSONObject hits = json.getJSONObject("hits");
                 hitsArray = hits.getJSONArray("hits");
                    for (int i=0; i<hitsArray.length(); i++) {
                    JSONObject h = hitsArray.getJSONObject(i);
                    JSONObject sourceJObj = h.getJSONObject("_source");
                            responseObj = new JSONObject();
                            fileRelativePath = sourceJObj.optString("path").toString().concat(sourceJObj.optString("filename").toString());
                            responseObj.put("id", Integer.parseInt(sourceJObj.opt("id").toString()));
                            responseObj.put("fileRelativePath", fileRelativePath);
                            responseArray.put(responseObj);
    
                    }
                    System.out.println("Response Length -->"+responseArray.length()+"Response --->"+responseArray.toString());