Aggregate sequences

The aggregation API allows you to compute aggregated results from a set of sequences, such as getting the number of sequences in a project or checking what assets the different sequences in your project are associated with (along with the number of sequences for each asset). By specifying filter and/or advancedFilter, the aggregation will take place only over those sequences that match the filters. filter and advancedFilter behave the same way as in the list endpoint.

The default behavior, when the aggregate field is not specified the request body, is to return the number of sequences that match the filters (if any), which is the same behavior as when the aggregate field is set to count.

The following requests will both return the total number of sequences whose name begins with pump:

{
  "advancedFilter": {"prefix": {"property": ["name"], "value": "pump"}}
}

and

{
  "aggregate": "count",
  "advancedFilter": {"prefix": {"property": ["name"], "value": "pump"}}
}

The response might be:

{"items": [{"count": 42}]}
Setting aggregate to uniqueValues and specifying a property in properties (this field is an array, but currently only supports one property) will return all unique values (up to a maximum of 1000) that are taken on by that property across all the sequences that match the filters, as well as the number of sequences that have each of those property values.

This example request finds all the unique asset ids that are referenced by the sequences in your project whose name begins with pump:

{
  "aggregate": "uniqueValues",
  "properties": [{"property": ["assetId"]}],
  "advancedFilter": {"prefix": {"property": ["name"], "value": "pump"}}
}

The response might be the following, saying that 23 sequences are associated with asset 18 and 107 sequences are associated with asset 76:

{
  "items": [
    {"values": ["18"], "count": 23},
    {"values": ["76"], "count": 107}
  ]
}
Setting aggregate to cardinalityValues will instead return the approximate number of distinct values that are taken on by the given property among the matching sequences.

Example request:

{
  "aggregate": "cardinalityValues",
  "properties": [{"property": ["assetId"]}],
  "advancedFilter": {"prefix": {"property": ["name"], "value": "pump"}}
}

The result is likely exact when the set of unique values is small. In this example, there are likely two distinct asset ids among the matching sequences:

{"items": [{"count": 2}]}
Setting aggregate to uniqueProperties will return the set of unique properties whose property path begins with path (which can currently only be ["metadata"]) that are contained in the sequences that match the filters.

Example request:

{
  "aggregate": "uniqueProperties",
  "path": ["metadata"],
  "advancedFilter": {"prefix": {"property": ["name"], "value": "pump"}}
}

The result contains all the unique metadata keys in the sequences whose name begins with pump, and the number of sequences that contains each metadata key:

{
  "items": [
    {"values": [{"property": ["metadata", "tag"]}], "count": 43},
    {"values": [{"property": ["metadata", "installationDate"]}], "count": 97}
  ]
}
Setting aggregate to cardinalityProperties will instead return the approximate number of different property keys whose path begins with path (which can currently only be ["metadata"], meaning that this can only be used to count the approximate number of distinct metadata keys among the matching sequences).

Example request:

{
  "aggregate": "cardinalityProperties",
  "path": ["metadata"],
  "advancedFilter": {"prefix": {"property": ["name"], "value": "pump"}}
}

The result is likely exact when the set of unique values is small. In this example, there are likely two distinct metadata keys among the matching sequences:

{"items": [{"count": 2}]}

The aggregateFilter field may be specified if aggregate is set to cardinalityProperties or uniqueProperties. The structure of this field is similar to that of advancedFilter, except that the set of leaf filters is smaller (in, prefix, and range), and that none of the leaf filters specify a property. Unlike advancedFilter, which is applied before the aggregation (in order to restrict the set of sequences that the aggregation operation should be applied to), aggregateFilter is applied after the initial aggregation has been performed, in order to restrict the set of results.

Click here for more details about aggregateFilter.

When aggregate is set to uniqueProperties, the result set contains a number of property paths, each with an associated count that shows how many sequences contained that property (among those sequences that matched the filter and advancedFilter, if they were specified) . If aggregateFilter is specified, it will restrict the property paths included in the output. Let us add an aggregateFilter to the uniqueProperties example from above:

{
  "aggregate": "uniqueProperties",
  "path": ["metadata"],
  "advancedFilter": {"prefix": {"property": ["name"], "value": "pump"}},
  "aggregateFilter": {"prefix": {"value": "t"}}
}

Now, the result only contains those metadata properties whose key begins with t (but it will be the same set of metadata properties that begin with t as in the original query without aggregateFilter, and the counts will be the same):

{
  "items": [
    {"values": [{"property": ["metadata", "tag"]}], "count": 43}
  ]
}

Similarly, adding aggregateFilter to cardinalityProperties will return the approximate number of properties whose property key matches aggregateFilter from those sequences matching the filter and advancedFilter (or from all sequences if neither filter nor aggregateFilter are specified):

{
  "aggregate": "cardinalityProperties",
  "path": ["metadata"],
  "advancedFilter": {"prefix": {"property": ["name"], "value": "pump"}},
  "aggregateFilter": {"prefix": {"value": "t"}}
}

As we saw above, only one property matches:

{"items": [{"count": 1}]}

Note that aggregateFilter is also accepted when aggregate is set to cardinalityValues or cardinalityProperties. For those aggregations, the effect of any aggregateFilter could also be achieved via a similar advancedFilter. However, aggregateFilter is not accepted when aggregate is omitted or set to count.

Rate and concurrency limits

Rate and concurrency limits apply this endpoint. If a request exceeds one of the limits, it will be throttled with a 429: Too Many Requests response. More on limit types and how to avoid being throttled is described here.

Limit Per project Per user (identity)
Rate 15 requests per second 10 requests per second
Concurrency 6 concurrent requests 4 concurrent requests
Securityoidc-token or oauth2-client-credentials or oauth2-open-industrial-data or oauth2-auth-code
Request
Request Body schema: application/json

Aggregates the sequences that match the given criteria.

One of:
(Boolean filter (and (object) or or (object) or not (object))) or (Leaf filter (equals (object) or in (object) or range (object) or prefix (object) or exists (object) or containsAny (object) or containsAll (object) or search (object))) (TimeSeriesFilterLanguage)

A filter DSL (Domain Specific Language) to define advanced filter queries.

At the top level, an advancedFilter expression is either a single Boolean filter or a single leaf filter. Boolean filters contain other Boolean filters and/or leaf filters. The total number of filters may be at most 100, and the depth (the greatest number of times filters have been nested inside each other) may be at most 10. The search leaf filter may at most be used twice within a single advancedFilter, but all other filters can be used as many times as you like as long as the other limits are respected.

(Boolean filter (and (object) or or (object) or not (object))) or (Leaf filter (in (object) or range (object) or prefix (object))) (TimeSeriesAggregateFilter)

A filter DSL (Domain Specific Language) to define aggregate filters.

object (SequenceFilter)
aggregate
string

The count aggregation gets the number of sequences that match the filter(s). This is the default aggregation, which will also be applied if aggregate is not specified.

Value: "count"
Responses
200

Response with the aggregated sequences. The type of the response depends on the value of the aggregate parameter in the request.

400

The response for a failed request.

post/sequences/aggregate
Request samples
application/json
{
  • "advancedFilter": {
    • "or": [
      ]
    },
  • "aggregateFilter": {
    • "and": [
      ]
    },
  • "filter": {
    • "name": "string",
    • "externalIdPrefix": "my.known.prefix",
    • "metadata": {
      },
    • "assetIds": [
      ],
    • "rootAssetIds": [
      ],
    • "assetSubtreeIds": [
      ],
    • "createdTime": {
      },
    • "lastUpdatedTime": {
      },
    • "dataSetIds": [
      ]
    },
  • "aggregate": "count"
}
Response samples
application/json
{
  • "items": [
    • {
      }
    ]
}