Currently, I have a field which is a map. I need to aggregate on the unique keys and the sum of its value.
{
"_index": "inx-flow",
"_type": "default",
"_id": "acc4566-23456",
"_score": 0.0,
"_source": {
"@Timestamp": "2018-06-20T09:21:43.892Z",
"taskType": "typeOne",
"imageId": "adadiddidd123",
"taskCreated": "2018-06-20T09:21:43.841Z",
"scope": {
"productA": 5
},
"taskPriority": 123,
"taskName": "typeOneName",
"metrics": {},
"taskId": "acc4566-23456",
"taskEvent": "Pending"
}
}
{
"_index": "inx-flow",
"_type": "default",
"_id": "acc4566-23456",
"_score": 0.0,
"_source": {
"@Timestamp": "2018-06-20T09:21:43.892Z",
"taskType": "typeOne",
"imageId": "adadiddidd123",
"taskCreated": "2018-06-20T09:21:43.841Z",
"scope": {
"productA": 1
},
"taskPriority": 123,
"taskName": "typeOneName",
"metrics": {},
"taskId": "acc4566-23456",
"taskEvent": "Pending"
}
}
{
"_index": "inx-flow",
"_type": "default",
"_id": "acc4566-23456",
"_score": 0.0,
"_source": {
"@Timestamp": "2018-06-20T09:21:43.892Z",
"taskType": "typeOne",
"imageId": "adadiddidd123",
"taskCreated": "2018-06-20T09:21:43.841Z",
"scope": {
"productB": 1
},
"taskPriority": 123,
"taskName": "typeOneName",
"metrics": {},
"taskId": "acc4566-23456",
"taskEvent": "Pending"
}
}
For the above, if I want to aggregate of scope across entries I want aggregation like ProductA 6 ProductB 1 How to achieve it. I am able to achieve if I hardcore the field names but I don't want hardcoded values. My code
try ( RestHighLevelClient restHighLevelClient = restHighLevelClient()){
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd");
LocalDate todayDate = LocalDate.now();
LocalDate yesterday = todayDate.minusDays(5);
String toDate = dtf.format(todayDate);
String fromDate = dtf.format(yesterday);
SearchRequest searchRequest = new SearchRequest(indexName);
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.size(10000);
searchSourceBuilder.query(QueryBuilders.boolQuery().
filter(QueryBuilders.commonTermsQuery("taskEvent", "Pending")).
filter(QueryBuilders.rangeQuery("@Timestamp").from(fromDate).to(toDate)));
TermsAggregationBuilder aggregation = AggregationBuilders.terms("scope")
.field("scope.productA");
aggregation.subAggregation(AggregationBuilders.sum("sum")
.field("scope.productA"));
searchSourceBuilder.aggregation(aggregation);
searchRequest.source(searchSourceBuilder);
SearchResponse searchResponse = restHighLevelClient.search(searchRequest);
SearchHit[] hits = searchResponse.getHits().getHits();
for(SearchHit hit : hits){
Map responseMap = hit.getSourceAsMap();
responseMap.forEach((key,value)->
System.out.println("Key "+key+ " Value "+value));
}
System.out.println("**********"+searchResponse.getHits().getHits().length);
System.out.println("********* " + searchResponse.getAggregations());
Terms agg = searchResponse.getAggregations().get("scope");
for(Terms.Bucket bucket : agg.getBuckets()){
Sum sum = bucket.getAggregations().get("sum");
System.out.println("Sum " + sum.getValue());
}
}
Could you help me understand how to aggregate without hard-coding the key name? Like I want to give the map root and aggregation should be based on the key and its values