I'm new on spring data elastic and i'm facing issue about query aggregation. My stack is : spring boot 3, spring 6, elastic client 8.5.x. My elastic search host version is 7.xx. So let's assume we have this query on elastic
GET someIndex-* /_search
{
"size": 0,
"query": {
"bool": {
"filter": [
{
"range": {
"@timestamp": {
"gte": "1688688000000",
"lte": "1688774399999",
"format": "epoch_millis"
}
}
},
{
"query_string": {
"analyze_wildcard": true,
"query": "name: alise"
}
}
]
}
},
"aggs": {
"by_term": {
"terms": {
"field": "Product_type.keyword",
"size": 10,
"order": {
"total_sum_metric": "desc"
},
"min_doc_count": 1
},
"aggs": {
"total_sum_metric": {
"sum": {
"field": "metric"
}
},
"group_by_date": {
"date_histogram": {
"interval": "30s",
"field": "@timestamp",
"min_doc_count": 1,
"extended_bounds": {
"min": "1688688000000",
"max": "1688774399999"
},
"format": "epoch_millis"
},
"aggs": {
"total_sum_metric": {
"sum": {
"field": "metric"
}
}
}
}
}
}
}
}
I wrote this query to spring data native query.
public void retrieveApplicationDetails(String applicationName, @NonNull LocalDateTime startDateTime, @NonNull LocalDateTime endDateTime) {
final var startmilliSecond = startDateTime
.atZone(ZoneOffset.UTC)
.toInstant()
.toEpochMilli();
final var endmilliSecond = endDateTime
.minusMinutes(1)
.atZone(ZoneOffset.UTC)
.toInstant()
.toEpochMilli();
final var query = buildSearchQuery(applicationName, startmilliSecond, endmilliSecond);
SearchHits<Object> search = elasticsearchOperations.search(query, Object.class, IndexCoordinates.of("Index-*"));
private static NativeQuery buildSearchQuery(String applicationName, long startmilliSecond, long endmilliSecond) {
var rangeQuery = new Query.Builder()
.range(ran -> ran
.field("@timestamp")
.format("epoch_millis")
.gte(JsonData.of(startmilliSecond))
.lte(JsonData.of(endmilliSecond)))
.build();
var queryString = new QueryStringQuery.Builder()
.query("name: %s".formatted(applicationName))
.analyzeWildcard(true)
.build()
._toQuery();
final var termsAggregation = TermsAggregation.of(termBuilder -> termBuilder
.field("Product_type.keyword")
.size(10)
.minDocCount(1)
.order(new NamedValue<>("total_sum_metric", SortOrder.Desc)));
final var sumAggregation = SumAggregation.of(metricAggregation -> metricAggregation.field("metric"));
final var query = QueryBuilders.bool(boolBuilder -> boolBuilder.filter(List.of(rangeQuery, queryString)));
final var groupByDateAggregation = Aggregation.of(byDateBuilder -> byDateBuilder
.dateHistogram(dateHistoBuilder -> dateHistoBuilder
.field("@timestamp")
.fixedInterval(intervalBuilder -> intervalBuilder.time("30s"))
.minDocCount(1)
.extendedBounds(extendsBoundBuilder -> extendsBoundBuilder
.min(FieldDateMath.of(minBuilder -> minBuilder.value((double) startmilliSecond)))
.max(FieldDateMath.of(maxBuilder -> maxBuilder.value((double) endmilliSecond))))
.format("epoch_millis")
)
.aggregations("total_sum_metric", sumAggregation));
final var byTermAggregation = Aggregation.of(aggBuilder -> aggBuilder
.terms(termsAggregation)
.aggregations("total_sum_metric", Aggregation.of(sumMetricBuilder -> sumMetricBuilder
.sum(sumAggregation)
.aggregations("group_by_date", groupByDateAggregation))));
return NativeQuery
.builder()
.withQuery(query)
.withAggregation("by_term", byTermAggregation)
.withMaxResults(0)
.withPageable(PageRequest.of(0, MAX_PAGE_REQUEST_SIZE))
.build();
}
So when I'm trying to request this on my elastic I'm getting this error Aggregator [total_sum_metric] of type [sum] cannot accept sub-aggregation. Some one knows what is my mistakes ? Thanks to those who will take the time to read me
my issue was in byTermAggregation. I added another nested aggregation on total_sum_metric. this is the good query :
final var byTermAggregation = Aggregation.of(aggBuilder -> aggBuilder
.terms(termsAggregation)
.aggregations("total_sum_metric", Aggregation.of(sumMetricBuilder -> sumMetricBuilder.sum(sumAggregation))
.aggregations("group_by_date", groupByDateAggregation))));