title: Better Java API for elasticsearch?
body: <p>I am starting out on Elasticsearch. The scalability and performance is awesome, but I'm having trouble with the java API. Given some profile data where the id is a username and the profile contains attributes and scores (eg strength : 30, dexterity : 72, magic : 48) I want to get the top profiles for a particular combination of attributes eg strength + dexterity, or strength + magic etc.</p>
  
  <p>Here is a query that I've used in Sense, which does exactly what I need:</p>
  
  <pre><code>GET_search{
      "size": 0,
      "aggs": {
          "group by profile": {
              "terms": {
                  "field": "profileId",
                  "order": {
                      "score_return": "desc"
                  }
              },
              "aggs": {
                  "score_return": {
                      "sum": {
                          "script": "doc['strength'].value + doc['dexterity'].value"
                      }
                  }
              }
          }
      }
  }
  </code></pre>
  
  <p>So now I want to port this query into my Java code. I managed to get it working, but it feels like it's extremely ugly - is there a better way of querying this data, or perhaps some library out there with a nice API, that can bind results to fields with annotations etc? Any suggestions welcome. This is what I have so far (it works, I just don't like the look of the code):</p>
  
  <pre><code>private void run() throws UnknownHostException {
  
      InetAddress inetAddress = InetAddress.getByName(HOST_IP);
      InetSocketTransportAddress transportAddress = new InetSocketTransportAddress(inetAddress, HOST_PORT);
  
      Client client = TransportClient.builder().build().addTransportAddress(transportAddress);
  
  
      String queryString = "{ \"aggs\": {  \"group by profile\": {   \"terms\": {   \"field\": \"profileId\", \"order\": { \"score_return\": \"desc\" } }, \"aggs\": { \"score_return\": { \"sum\": { \"script\": \"doc['dexterity'].value + doc['strength'].value\" } } } } } }";
  
      //Sample Query - JSONObject
      //We convert the raw query string to JSONObject to avoid query parser error in Elasticsearch
      JSONObject queryStringObject = new JSONObject(queryString);
  
      //Elasticsearch Response
      SearchResponse response = client.prepareSearch("profiles").setTypes("profile").setSource(queryStringObject.toString()).execute().actionGet();
  
      //Elasticsearch Response Hits
      SearchHits hits = response.getHits();
      Aggregations aggregations = response.getAggregations();
  
      Map&lt;String, Aggregation&gt; aggsMap = aggregations.asMap();
      Aggregation groupBy = aggsMap.get("group by profile");
      System.out.println(groupBy);
  
      StringTerms st = ((StringTerms)groupBy);
      System.out.println(st);
  
      List&lt;Bucket&gt; buckets = st.getBuckets();
      for(Bucket bucket : buckets) {
          System.out.println(bucket.getKeyAsString());
          Aggregation score = bucket.getAggregations().get("score_return");
          String value = ((InternalSum)score).getValueAsString();
          System.out.println(value);
      }
  
      client.close();
  
  }
  </code></pre>