Hi, I have tried to modify your code, suiting to your requirement and the code shared by you as per my understanding. Please try to implement the same and let me know if it works. Thanks !!
public BucketList getListOfBucket(final BucketListInfo bucketListInfo, String afterKey, int size) {
final SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
//we need to create the list of aggregating fields
List<CompositeValuesSourceBuilder<?>> sourceBuilderList=new ArrayList<>();
for (final String aggrField : bucketListInfo.getAggrFieldList()) {
//in field method pass the name of elastic search field name (es_field_name)
//in TermsValuesSourceBuilder constructor pass the distinct name for that field to be identified in the resulting hash map (key_name_for_field)
TermsValuesSourceBuilder compositeValueTerm= new TermsValuesSourceBuilder(key_name_for_field).field(es_field_name)));
sourceBuilderList.add(compositeValueTerm);
}
//Composite aggregation builder has to be present outside as for all the fields present in bucketListInfo.getAggrFieldList() we have to create one aggreation
//we need to specify some name for our entire aggregation ( bucket_name)
CompositeAggregationBuilder aggregationBuilder = AggregationBuilders.composite(bucket_name, sourceBuilderList);
aggregationBuilder.aggregateAfter(Map.of(aggrField, aggrField))//its value need to filled after every previous search response
searchSourceBuilder.size(size).aggregation(aggregationBuilder);
final SearchRequest searchRequest = new SearchRequest(bucketListInfo.getIndexName()).source(searchSourceBuilder);
try {
final SearchResponse response = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
return extractBucketsFromResponse(bucketListInfo, response);
} catch (Exception e) {
log.error(e.getMessage(), e);
return null;
}
}
//iteration code
Map<String, Object> afterKey = null;
BucketListInfo bInfo=new BucketListInfo(); //change it according to your code
BucketList bucketList = getListOfBucket(bIfno, afterKey, 100); // after key will be null for first iteration, size=100
SearchResponse searchResponse=bucketList.getSearchResponse(); //assuming entire search response is present in bucketList
while (searchResponse != null && searchResponse.getAggregations() != null) {
List<Aggregation> aggregationList = searchResponse.getAggregations().asList();
if (CollectionUtils.isNotEmpty(aggregationList)) {
for (Aggregation aggregation : aggregationList) {
ParsedComposite parsedComposite = (ParsedComposite) aggregation;
afterKey = parsedComposite.afterKey(); //after key comes in search response
parsedComposite.getBuckets().forEach(parsedBucket -> parsedBucket.getKey().forEach((k, v) -> //values of the bucket you can store in list);
}
}
if (afterKey != null) { //aggregation buckets
searchResponse = getListOfBucket(bIfno, afterKey, 100)
} else {
searchResponse = null; //when the entire data set is over, response would be null to end the while loop
}
}