---
type: api
title: Search rolled-up data
description: **All methods and paths for this operation:**
url: https://www.elastic.co/elastic/docs-builder/docs/4371/api/doc/elasticsearch/v8/operation/operation-rollup-rollup-search
resource: https://www.elastic.co/elastic/docs-builder/docs/4371/api/doc/elasticsearch/v8/operation/operation-rollup-rollup-search
products:
  - Elasticsearch
---

# Search rolled-up data


deprecated

Availability: 6.3+

## Paths

- `POST` (also `GET`) `/{index}/_rollup_search`

- [Api key auth](/elastic/docs-builder/docs/4371/api/doc/elasticsearch/v8/authentication#apikeyauth)
- [Basic auth](/elastic/docs-builder/docs/4371/api/doc/elasticsearch/v8/authentication#basicauth)
- [Bearer auth](/elastic/docs-builder/docs/4371/api/doc/elasticsearch/v8/authentication#bearerauth)

#### Path Parameters

- `index` (union IndexName | [] IndexName)
  A comma-separated list of data streams and indices used to limit the request.
This parameter has the following rules:

* At least one data stream, index, or wildcard expression must be specified. This target can include a rollup or non-rollup index. For data streams, the stream's backing indices can only serve as non-rollup indices. Omitting the parameter or using `_all` are not permitted.
* Multiple non-rollup indices may be specified.
* Only one rollup index may be specified. If more than one are supplied, an exception occurs.
* Wildcard expressions (`*`) may be used. If they match more than one rollup index, an exception occurs. However, you can use an expression to match multiple non-rollup indices or data streams.

## Description

The rollup search endpoint is needed because, internally, rolled-up documents utilize a different document structure than the original data.
It rewrites standard Query DSL into a format that matches the rollup documents then takes the response and rewrites it back to what a client would expect given the original query.

The request body supports a subset of features from the regular search API.
The following functionality is not available:

`size`: Because rollups work on pre-aggregated data, no search hits can be returned and so size must be set to zero or omitted entirely.
`highlighter`, `suggestors`, `post_filter`, `profile`, `explain`: These are similarly disallowed.

**Searching both historical rollup and non-rollup data**

The rollup search API has the capability to search across both "live" non-rollup data and the aggregated rollup data.
This is done by simply adding the live indices to the URI. For example:

```
GET sensor-1,sensor_rollup/_rollup_search
{
  "size": 0,
  "aggregations": {
     "max_temperature": {
      "max": {
        "field": "temperature"
      }
    }
  }
}
```

The rollup search endpoint does two things when the search runs:

* The original request is sent to the non-rollup index unaltered.
* A rewritten version of the original request is sent to the rollup index.

When the two responses are received, the endpoint rewrites the rollup response and merges the two together.
During the merging process, if there is any overlap in buckets between the two responses, the buckets from the non-rollup index are used.

## Query String Parameters

- `rest_total_hits_as_int` (boolean · default: false)
  Indicates whether hits.total should be rendered as an integer or an object in the rest search response
- `typed_keys` (boolean · default: false)
  Specify whether aggregation and suggester names should be prefixed by their respective types in the response

## Request Body

`application/json`

- `aggregations` (map string to {} AggregationContainer) — optional
  Specifies aggregations.
  See [AggregationContainer](https://www.elastic.co/elastic/docs-builder/docs/4371/api/doc/elasticsearch/v8/types/_types-aggregations-aggregationcontainer)
- `query` ({} QueryContainer) — optional
  Specifies a DSL query that is subject to some limitations.
  See [QueryContainer](https://www.elastic.co/elastic/docs-builder/docs/4371/api/doc/elasticsearch/v8/types/_types-query_dsl-querycontainer)
- `size` (number) — optional
  Must be zero if set, as rollups work on pre-aggregated data.

## Response

`application/json`

- `took` (number)
- `timed_out` (boolean)
- `terminated_early` (boolean)
- `_shards` ({} ShardStatistics)
  - `failed` (number uint)
    The number of shards the operation or search attempted to run on but failed.
  - `successful` (number uint)
    The number of shards the operation or search succeeded on.
  - `total` (number uint)
    The number of shards the operation or search will run on overall.
  - `failures` ([] ShardFailure)
    - `index` (string IndexName)
    - `node` (string)
    - `reason` ({} ErrorCause)
      - `type` (string)
        The type of error
      - `reason` (union string) — nullable
        A human-readable explanation of the error, in English.
        One of: `string`
      - `stack_trace` (string)
        The server stack trace. Present only if the `error_trace=true` parameter was sent with the request.
      - `caused_by` ({} ErrorCause) — recursive
        Same fields as `reason` in `failures`
      - `root_cause` ([] ErrorCause) — recursive
        Same fields as `reason` in `failures`
      - `suppressed` ([] ErrorCause) — recursive
        Same fields as `reason` in `failures`
    - `shard` (number)
    - `status` (string)
    - `primary` (boolean)
  - `skipped` (number uint)
- `hits` ({} HitsMetadata)
  - `total` (union oneOf)
    Total hit count information, present only if `track_total_hits` wasn't `false` in the search request.
    - **TotalHits**
      - `relation` (enum TotalHitsRelation)
        

Supported values include:
  - `eq`: Accurate
  - `gte`: Lower bound, including returned events or sequences
        Values: `eq`, `gte`
      - `value` (number)
    - **number**
  - `hits` ([] Hit)
    - `_index` (string IndexName)
    - `_id` (string Id)
    - `_score` (union number | string) — nullable
    - `_explanation` ({} Explanation)
      - `description` (string)
      - `details` ([] ExplanationDetail)
        - `description` (string)
        - `details` ([] ExplanationDetail) — recursive
          Same fields as `details` in `_explanation`
        - `value` (number)
      - `value` (number)
    - `fields` (map string to object)
    - `highlight` (map string to string)
    - `inner_hits` (map string to InnerHitsResult)
      Map values ({} InnerHitsResult)
      - `hits` ({} HitsMetadata) — recursive
        Same fields as `hits`
    - `matched_queries` (union oneOf)
      One of: `string[]` or `string to number`
    - `_nested` ({} NestedIdentity)
      - `field` (string Field)
      - `offset` (number)
      - `_nested` ({} NestedIdentity) — recursive
        Same fields as `_nested` in `hits`
    - `_ignored` ([] string)
    - `ignored_field_values` (map string to FieldValue)
    - `_shard` (string)
    - `_node` (string)
    - `_routing` (string)
    - `_source` (object)
    - `_rank` (number)
    - `_seq_no` (number SequenceNumber)
    - `_primary_term` (number)
    - `_version` (number VersionNumber)
    - `sort` (SortResults)
  - `max_score` (union number | string) — nullable
- `aggregations` (map string to {} Aggregate)
  See [Aggregate](https://www.elastic.co/elastic/docs-builder/docs/4371/api/doc/elasticsearch/v8/types/_types-aggregations-aggregate)
## Code Examples

#### Console

```console
POST /sensor_rollup/_rollup_search
{
  "size": 0,
  "aggregations": {
    "max_temperature": {
      "max": {
        "field": "temperature"
      }
    }
  }
}
```

#### JavaScript

```javascript
const response = await client.rollup.rollupSearch({
  index: "sensor_rollup",
  size: 0,
  aggregations: {
    max_temperature: {
      max: {
        field: "temperature",
      },
    },
  },
});
```

#### Python

```python
resp = client.rollup.rollup_search(
    index="sensor_rollup",
    size=0,
    aggregations={
        "max_temperature": {
            "max": {
                "field": "temperature"
            }
        }
    },
)
```

#### curl

```curl
curl -X POST "$ELASTICSEARCH_URL/sensor_rollup/_rollup_search" \
  -H "Authorization: ApiKey $ELASTIC_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "size": 0,
    "aggregations": {
      "max_temperature": {
        "max": {
          "field": "temperature"
        }
      }
    }
  }'
```

#### Java

```java
client.rollup().rollupSearch(r -> r
    .aggregations("max_temperature", a -> a
        .max(m -> m
            .field("temperature")
        )
    )
    .index("sensor_rollup")
    .size(0)
);
```

#### C#

```c#
var response = await client.Rollup
    .RollupSearchAsync<MyDocument>(indices: new[] { "sensor_rollup" }, d1 => d1
        .Aggregations(d2 => d2
            .Add("max_temperature", d3 => d3
                .Max(d4 => d4
                    .Field(x => x.Temperature)
                )
            )
        )
        .Size(0)
    );
```

#### PHP

```php
$resp = $client->rollup()->rollupSearch([
    "index" => "sensor_rollup",
    "body" => [
        "size" => 0,
        "aggregations" => [
            "max_temperature" => [
                "max" => [
                    "field" => "temperature",
                ],
            ],
        ],
    ],
]);
```

#### Ruby

```ruby
response = client.perform_request(
  "GET",
  "/sensor_rollup/_rollup_search",
  {},
  {
    "size": 0,
    "aggregations": {
      "max_temperature": {
        "max": {
          "field": "temperature"
        }
      }
    }
  },
  { "Content-Type": "application/json" },
)
```

## Response Examples

#### Rollup search response example1

An abbreviated response from `GET /sensor_rollup/_rollup_search` with a `max` aggregation on a `temperature` field. The response provides some metadata about the request (`took`, `_shards`), the search hits (which is always empty for rollup searches), and the aggregation response.

```json
{
  "took" : 102,
  "timed_out" : false,
  "terminated_early" : false,
  "_shards" : {} ,
  "hits" : {
    "total" : {
        "value": 0,
        "relation": "eq"
    },
    "max_score" : 0.0,
    "hits" : [ ]
  },
  "aggregations" : {
    "max_temperature" : {
      "value" : 202.0
    }
  }
}
```

