How to Paginate Aggregation Results in Elasticsearch
composite aggregation which supports the after parameter to fetch the next page of buckets. This method allows you to scroll through large aggregation results efficiently without missing or duplicating data.Syntax
The composite aggregation syntax includes a sources array defining the fields to aggregate on, and an optional after key to paginate results.
Key parts:
sources: List of fields to group by.size: Number of buckets to return per page.after: The last bucket key from the previous page to continue pagination.
{
"aggs": {
"my_buckets": {
"composite": {
"size": 10,
"sources": [
{ "field_name": { "terms": { "field": "field_name.keyword" } } }
],
"after": { "field_name": "last_value_from_previous_page" }
}
}
}
}Example
This example shows how to paginate aggregation results on a field called category.keyword. The first query fetches the first 3 buckets. The second query uses the after key from the first response to get the next 3 buckets.
{
"size": 0,
"aggs": {
"categories": {
"composite": {
"size": 3,
"sources": [
{ "category": { "terms": { "field": "category.keyword" } } }
]
}
}
}
}
--- Response snippet ---
"aggregations": {
"categories": {
"buckets": [
{ "key": { "category": "Books" }, "doc_count": 15 },
{ "key": { "category": "Clothing" }, "doc_count": 10 },
{ "key": { "category": "Electronics" }, "doc_count": 8 }
],
"after_key": { "category": "Electronics" }
}
}
--- Next query to get next page ---
{
"size": 0,
"aggs": {
"categories": {
"composite": {
"size": 3,
"sources": [
{ "category": { "terms": { "field": "category.keyword" } } }
],
"after": { "category": "Electronics" }
}
}
}
}Common Pitfalls
1. Using terms aggregation for pagination: The terms aggregation does not support pagination with an after key, so it cannot reliably paginate large result sets.
2. Forgetting to use after_key from the response: Always use the after_key from the previous response to fetch the next page; otherwise, you will get duplicate or missing buckets.
3. Changing the sources between requests: The sources array must remain the same for all paginated requests to maintain consistency.
{
"aggs": {
"wrong_pagination": {
"terms": {
"field": "category.keyword",
"size": 10
}
}
}
}
-- This will NOT paginate properly --
{
"aggs": {
"correct_pagination": {
"composite": {
"size": 10,
"sources": [
{ "category": { "terms": { "field": "category.keyword" } } }
],
"after": { "category": "last_value" }
}
}
}
}Quick Reference
- Use
compositeaggregation for paginating buckets. - Set
sizeto control buckets per page. - Use
afterkey from previous response to get next page. - Keep
sourcesconsistent across requests.