aggregate

fun QueryBackend.aggregate(query: AdmittedQuery<AggregationQuery>, budget: QueryBudget? = null): Flux<ObjectNode>

The groups of query. The core plans the residual operators the storage declares RESIDUAL: it removes them from the query it sends down, asks for every group when an operator needs them all, and applies dense fill, HAVING and top-N (or the limit) to the rows that come back. An aggregation without groups always has its summary row: when the backend emits none, because no record matched, the core emits the empty summary (EmptyAggregationValues). When it reads every group, budget's QueryBudget.maxResidualGroups bounds how many it processes, dense fill rows included: HAVING can discard every fill row, so without counting them a sparse fine-grained dense histogram would generate rows until the idle timeout.