Data Aggregation
Version 23.0.9145
Version 23.0.9145
Data Aggregation
The OData service exposed by API Server supports data aggregation and transformation, using the $apply
keyword as defined in the OData specifications.
Aggregate
The $apply
keyword supports the aggregate(...)
transformation, which takes as arguments a list of comma-separated aggregation expressions. API Server returns a result set corresponding to the aggregate method specified. This result set might have a different structure than the original resource.
Aggregation Expressions
Aggregation expressions follow the syntax: <ColumName> with <Method> as <Alias>
, where:
ColumnName
: is the entity upon which the aggregation method is evaluatedMethod
: is a supported aggregation methodsAlias
: is an OData-valid name to display the result of the aggregation in the result set
Supported Aggregation Methods
API Server supports the following aggregation methods:
countdistinct | Returns the number of separate, non-identical values on the column specified in the aggregated data set |
sum | Returns the sum of the values of the column specified over the aggregated data set |
max | Returns the maximum value of the column specified over the aggregated data set |
min | Returns the minimum value the column specified over the aggregated data set |
average | Returns the arithmetic mean of the column specified over the aggregated data set |
Virtual Aggregation $count
In addition to the aggregation methods listed above, API Server supports the $count
virtual aggregation method. This method uses a different syntax than the main aggregation methods. It does not specify a column, only an alias: $count as <Alias>
. The $count
method returns the number of separate entities in an aggregated data set.
Example Aggregation Requests:
Here are some example requests and result sets for the aggregation transformation:
Find the Number of Available Products
Request
GET Products$apply=aggregate($count as Total)
Response
{
"value": [
{"@odata.id": null, "Total": 24}
]
}
Return the Number of Product Categories with the Maximum Product Price
Request
GET Products?$apply=aggregate(Category with countdistinct as TotalCat, Price with max as MaxPrice)
Response
{
"value": [
{ "@odata.id": null, "TotalCat": 2, "MaxPrice": 1299.99}
]
}
Group By
The $apply
keyword also supports groupby(...)
transformations. This transformation takes one or two arguments. The first argument is a list of columns, enclosed in parentheses. The second argument, which is optional, is an aggregate transformation expression.
Grouping Properties
The grouping properties argument of the groupby()
transformation is a comma-separated list of columns, and is enclosed in parentheses. The transformation divides the available entities into data sets in which ALL specified grouping columns are equal.
Aggregation Transformation
When used in combination with groupby()
, the aggregation transformations apply to each data set individually. The aggregate transformation argument uses the same syntax as a standard aggregation.
Simple Groupby Examples
These examples specify only the first argument of the groupby()
transformation.
Find all Different Values for Product Categories
Request
GET Products?$apply=groupby((Category))
Response
{
"value": [
{ "@odata.id": null, "Category": "Bike" },
{ "@odata.id": null, "Category": "Shoes" }
]
}
Find all Combinations of Category and Color across Existing Products
Request
GET Products?$apply=groupby((Category,Color))
Response
{
"value": [
{ "@odata.id": null, "Category": "Bike", "Color": "Red" },
{ "@odata.id": null, "Category": "Bike", "Color": "Blue" },
{ "@odata.id": null, "Category": "Shoes", "Color": "Black" },
{ "@odata.id": null, "Category": "Shoes", "Color": "Blue" },
{ "@odata.id": null, "Category": "Shoes", "Color": "Red" }
]
}
Groupby and Aggregation Examples
These examples specify both arguments of the groupby()
transformation.
Find the Least Expensive Item in each Product Category
Request
GET Products?$apply=groupby((Category), aggregate(Price with min as MinPrice))
Response
{
"value": [
{ "@odata.id": null, "Category": "Bike", "MinPrice": 120},
{ "@odata.id": null, "Category": "Shoes", "MinPrice": 30}
]
}
Find the Number of Available Items for all Combinations of Category and Color, with the Average Price
Request
GET Products?$apply=groupby((Category,Color), aggregate($count as AvailProd, Price with average as AverageCost))
Response
{
"value": [
{ "@odata.id": null, "Category": "Bike", "Color": "Red" , "AvailProd": 12, "AverageCost": 514.34 },
{ "@odata.id": null, "Category": "Bike", "Color": "Blue" , "AvailProd": 7, "AverageCost": 520.17 },
{ "@odata.id": null, "Category": "Shoes", "Color": "Black", "AvailProd": 2, "AverageCost": 89.64 },
{ "@odata.id": null, "Category": "Shoes", "Color": "Blue" , "AvailProd": 9, "AverageCost": 79.84 },
{ "@odata.id": null, "Category": "Shoes", "Color": "Red" , "AvailProd": 4, "AverageCost": 98.63 }
]
}
Data Aggregation and Filtering
API Server supports filtering with a data aggregation query. The filter can apply to the result of the aggregation, or the aggregation can be applied to the results of the filter transformation.
Filtering Aggregated Data
The OData keywords $filter
, $orderby
, $top
and $skip
apply to the result of the aggregation. If you specify $skip
, you must also set an $orderby
value.
Request
GET Products?$apply=groupby((Color), aggregate($count as Total))&$filter=Total gt 0&$orderby=Total
Response
{
"value": [
{"@odata.id": null, "Color": "Blue", "Total": "1"},
{"@odata.id": null, "Color": "Red", "Total": "15"},
{"@odata.id": null, "Color": "Green", "Total": "32"},
{"@odata.id": null, "Color": "Black", "Total": "44"}
]
}
Aggregating on Filtered Data
To apply a filter on data prior to the aggregation, you can use the $apply
OData keyword to support the filter(...)
transformation. The value of the filter is the same as OData filters that use the $filter
keyword. The aggregation is applied on the result of the filtered data.
Request
GET Products?$apply=filter(ProductCategoryId eq 10)/groupby((Color, ProductCategoryId), aggregate($count as Total))
Response
{
"value": [
{"@odata.id": null, "ProductCategoryId": 10, "Color": "Red", "Total": 8},
{"@odata.id": null, "ProductCategoryId": 10, "Color": "Green", "Total": 12}
]
}