Required capabilities:
StreamRecordsAcl:READDataModelsAcl:READ
Aggregate data for records from the stream.
You can use an optional filter specification to limit the results.
The Records API supports three main groups of aggregates:
Metric aggregates: sum, min, max, count, etc.
Bucket aggregates (result records are aggregated into groups (buckets) — similar to the Data Model Instances groupBy concept):
uniqueValues (group by property values), timeHistogram (group by date/time ranges), filters (group by filter criteria), etc.
Pipeline aggregates: movingFunction.
Note: The pipeline aggregate applies to the results of another histogram aggregate.
It applies to metrics (such as count, min, max, sum, etc.), not to the records in the parent aggregate buckets.
This differs from sub-aggregates, which apply directly to records within each bucket.
Every aggregate request can contain multiple aggregate entries. Every bucket aggregate can contain multiple sub-aggregates (of any type), which are applied to records in each bucket of the parent aggregate.
Example:
Imagine there is paddle-tennis players game_statistics container with model:
{
game_id: Long,
game_time: Instant,
player_name: String,
points_scored: Int,
...
}
To get the following data:
for each day
calculate average number of points scored by players in all games on that day
and for each player
calculate the total number of points scored by the player in all games they participated in on that day
and find the max number of points scored by the player in all games they participated in on that day
and find the max number of points scored by players in all games they participated in during the entire search period.
Use aggregates like these (meta language):
timeHistogram(daily, game_time) // group by (form buckets) 1-day range based on `game_time` property values
avg(points_scored) // inside every day group calculate average value in `points_scored` property
uniqueValues(player_name) // inside every day group group by (form buckets) player names
sum(points_scored) // inside every player group which is inside every day group calculate the sum of points scored
max(points_scored) // inside every player group which is inside every day group find the maximum of points scored
max(points_scored) // find the maximum number of points scored across all statistic records (without any grouping)
Or the same in Cognite Records Aggregates DSL (Json):
{
"my_groups_by_1d_range": {
"timeHistogram": {
"calendarInterval": "1d",
"property": [ "paddle", "game_statistics", "game_time" ],
"aggregates": {
"my_groups_by_player_name": {
"uniqueValues": {
"property": [ "paddle", "game_statistics", "player_name" ],
"aggregates": {
"my_player_daily_scores_sum": {
"sum": { "property": [ "paddle", "game_statistics", "points_scored" ] }
},
"my_player_daily_scores_maximum": {
"max": { "property": [ "paddle", "game_statistics", "points_scored" ] }
}
}
}
},
"my_daily_scores_average": {
"avg": { "property": [ "paddle", "game_statistics", "points_scored" ] }
}
}
}
},
"my_scores_maximum_across_all_games": {
"max": { "property": [ "paddle", "game_statistics", "points_scored" ] }
}
}
and the response would be
{
"my_groups_by_1d_range": {
"timeHistogramBuckets": [
{
"count": 13
"intervalStart": "2025-05-25T00:00:00Z",
"aggregates": {
"my_groups_by_player_name": {
"uniqueValueBuckets": [
{
"count": 3
"value": "Vasya Rogov",
"aggregates": {
"my_player_daily_scores_sum": {
"sum": 57
},
"my_player_daily_scores_maximum": {
"max": 25
}
}
},
{
"count": 5
"value": "Vinni Pooh",
"aggregates": {
"my_player_daily_scores_sum": {
"sum": 53
},
"my_player_daily_scores_maximum": {
"max": 21
}
}
},
...
]
},
"my_daily_scores_average": {
"avg": 33
}
}
},
{
"count": 7
"intervalStart": "2025-05-26T00:00:00Z",
"aggregates": {
"my_groups_by_player_name": {
"uniqueValueBuckets": [
{
"count": 1
"value": "Vasya Rogov",
"aggregates": {
"my_player_daily_scores_sum": {
"sum": 24
},
"my_player_daily_scores_maximum": {
"max": 24
}
}
},
{
"count": 2
"value": "Pyatochok",
"aggregates": {
"my_player_daily_scores_sum": {
"sum": 42
},
"my_player_daily_scores_maximum": {
"max": 23
}
}
},
...
]
},
"my_daily_scores_average": {
"avg": 22
}
}
},
...
]
},
"my_scores_maximum_across_all_games": {
"max": 42
}
}
Aggregation specification.
object (lastUpdatedTime) Matches records with the last updated time within the provided range. This attribute is mandatory for immutable streams but it's optional for mutable streams. The maximum time interval that can be defined by the attribute is limited by the stream settings. If more data needs to be queried than allowed by the stream settings, it should be done with multiple requests. For example, if stream allows querying up to 1 month of data, but a quarterly report is needed, the solution is to make 3 requests, one for each month, and then aggregate the responses. The range must include at least a left ( Note: The range bounds can be specified in two formats:
| |
(boolFilter (and (object) or or (object) or not (object))) or (leafFilter (matchAll (object) or exists (object) or equals (object) or hasData (object) or prefix (object) or range (object) or in (object) or containsAll (object) or containsAny (object))) (filter) A filter Domain Specific Language (DSL) used to create advanced filter queries. Note: the max number of nodes in the filter tree is 100 and the max tree depth is 10. | |
required | object (aggregatesDictionary) [ 1 .. 5 ] properties unique A dictionary of requested aggregates with client defined names/identifiers. Example:
Max number of (sub-)aggregate trees on a level is 5, Max aggregate tree depth is 5. Max number of aggregates in the forest is 16. |
Aggregated query results.
The response for a failed request.
{- "lastUpdatedTime": {
- "gt": 1705341600000,
- "lt": "2030-05-15T18:00:00.00Z"
}, - "filter": {
- "and": [
- {
- "containsAll": {
- "property": [
- "mySpace",
- "myContainer",
- "myProperty"
], - "values": [
- 10011,
- 10012
]
}
}, - {
- "range": {
- "property": [
- "my_space",
- "my_container",
- "my_weight"
], - "gte": 0
}
}
]
}, - "aggregates": {
- "my_avg_aggregate1": {
- "avg": {
- "property": [
- "mySpace",
- "myContainer",
- "manufacturer"
]
}
}, - "my_terms_aggregate2": {
- "uniqueValues": {
- "property": [
- "mySpace",
- "myContainer",
- "manufacturer"
], - "aggregates": {
- "my_sub_aggregate1": {
- "min": {
- "property": [
- "mySpace",
- "myContainer",
- "price"
]
}
}, - "my_sub_aggregate2": {
- "max": {
- "property": [
- "mySpace",
- "myContainer",
- "price"
]
}
}, - "my_sub_aggregate3": {
- "uniqueValues": {
- "property": [
- "mySpace",
- "myContainer",
- "region"
]
}
}
}
}
}
}
}{- "aggregates": {
- "my_avg_aggregate1": {
- "avg": 42
}, - "my_terms_aggregate2": {
- "uniqueValueBuckets": [
- {
- "value": "Cognite",
- "count": 42,
- "aggregates": {
- "my_sub_aggregate1": {
- "min": 13
}, - "my_sub_aggregate2": {
- "max": 69
}, - "my_sub_aggregate3": {
- "uniqueValueBuckets": [
- {
- "value": "us1",
- "count": 42
}, - {
- "value": "ie1",
- "count": 7
}
]
}
}
}, - {
- "value": "AkerBP",
- "count": 21,
- "aggregates": {
- "my_sub_aggregate1": {
- "min": 99
}, - "my_sub_aggregate2": {
- "max": 999
}, - "my_sub_aggregate3": {
- "uniqueValueBuckets": [
- {
- "value": "us1",
- "count": 11
}
]
}
}
}
]
}
}
}