GraphQL queries
You can query the instances with GraphQL. The query capabilities of the GraphQL API interface represent a subset of the capabilities available from the DMS query endpoints.
A query has these key sections:
-
A query intent
query MyQueryName {(or just{as shorthand). -
The query to run. This can be one of four types of queries (with an optional alias, for example,
myAlias: listActor):-
list<type>, for example,listActorlists based on filter parameters. -
get<type>ById, for example,getActorByIdlists based on filter parameters. -
search<type>, for example,searchActorsearches based on a query parameter. -
aggregate<type>, for example,aggregateActoraggregates (count, average etc.) based on a field.See the query types section for more details.
-
-
The query parameters. For example,
filter: {...}orlimit: 1000. -
The properties to return at a specified depth.
GraphQL list and getById queries aren't designed for retrieving large datasets. Refer to GraphQL list and getbyid queries with subqueries for more information.
GraphQL example
query myQuery {
listCountry {
items {
name
demographics {
populationSize
growthRate
}
deaths {
datapoints(limit: 100) {
timestamp
value
}
}
}
pageInfo {
endCursor
}
}
listDemographics(
filter: {
and: [{ populationSize: { gte: 2 } }, { populationSize: { lte: 10 } }]
}
) {
items {
populationSize
growthRate
metadata {
key
value
}
}
}
}
Where:
myQuerydeclares the query intent.listCountryandlistDemographicsare the queries to run.- The parameters are
Country:100for thedeathstime series data points, and theDemographics: filter ofpopulationSizebetween 2 and 10. - The properties to return, for
Country:items->name,demographic->populationSize,growthRate, etc.
For more information, see the GraphQL documentation.
Query types
Use these basic query types: "list", "getById", "search" and "aggregate".
list queries
list<type> lets you filter and sort data quickly. For list<type> you can use these
properties and parameters:
-
Properties
items: specify the properties to return data forpageInfo: details about the current set of returned items and cursors used to paginate to the next page of data.
-
Parameters
filter: the filter you want to use based on thepropertiesin your graph. You can useand,or, andnotoperators to create complex queries.sort: the ordering of the returned data you want. Specify an array of one or morepropertiesto sort the data on, and whether the data should be sorted inASCorDESCorder.after: where in the result set to continue from, using theendCursorvalue from the previous query.first: the maximum number of items to return. To fetch more items use a new query, and supply the value from the previous query'sendCursorparameter. (Default maximum: 1000 instances)
Pagination
Pagination is only supported at the top level when using list<type> queries.
For a query like the one below, cursors will only be returned to paginate through the data returned from Movies, but not from Actors. If you need to paginate through nested types, for actors in this example, use the get<type>ById queries instead:
query ListMovies {
listMovie {
items {
title
actors {
name
}
}
pageInfo {
endCursor
}
}
}
getById queries
Use get<type>ById to fetch a specific item by its externalId. For get<type>ById, you can use similar properties and parameters as list queries. Pagination for nested items is available when using get<type>ById.
-
Properties
items: specify which properties to return.
search queries
Use search<type> to search and query data quickly. For search<type> you can use these properties and parameters:
-
Properties - The same as for the
listqueries. -
Parameters
filter: the filter you want to provide based on thepropertiesin your data model. You can use an array ofand,or, andnotto create more complex queries.fields: the properties you want to search on. This can be an array ofproperties.query: the actual search queries. Wildcards are supported.first: the maximum number of items to return. To fetch more items, use a new query using theendCursorparameter.(Default: 1000)
aggregate queries
Use aggregate<type> to aggregate data and compute rollups on the instances in a type. For aggregate<type>, you can use these properties and parameters:
-
Properties
group: depending on thegroupByparameter, this indicates the group. The group is the name of each aggregation bucket based on the value(s) of the field(s) used in thegroupByparameter.avg: for number properties, you can ask for the average.count: for any type of properties, you can ask for the total count.histogram(interval: <number>): for number properties, you can ask for the histogram for an interval.max: for number properties, you can ask for the maximum value.min: for number properties, you can ask for the minimum value.sum: for number properties, you can ask for the total sum.pageInfo: the details about the current set of returned items. The existence ofendCursorindicates that there is another page of data.
-
Parameters
filter: perform the aggregation on instances matching a logical expression. This filter is applied to thefieldsin your data type as described below, and you can use an array ofand,or, andnotto create more complex queries. For text field searches other than prefix matching, usequery.query: applies a full-text search to textfieldsin the type and performs the aggregation on instances matching the query and filter. The query is, by default, applied to all text fields in the type, but can be constrained to a subset of thefields using thefieldsparameter.fields: the properties or fields you want to search in with thequerysearch. This can be an array offields.groupBy: thefield(s) to group by (no relationship allowed).after: thenextCursorfrom the previous query, for pagination.
Filter specifications
| Field | Filter | How to use | |
|---|---|---|---|
| Top level filters | Any | and | {and: [{...},{...}]} = if everything is true. |
or | {or: [{...},{...}]} = if at least one is true. | ||
not | {not: {...}} = if false. | ||
| Primitives | Any | eq | {eq: ...} |
in | {in: ["..."]} = if any of term. | ||
| Nullable | isNull | {isNull: True} = if the field is empty. | |
| String | prefix | {prefix: "..."} = starts with. | |
| Int/Int64/Float/Timestamp | lt | {lt: ...} = less than. | |
gt | {gt: ...} = greater than. | ||
lte | {lte: ...} = less than or equals. | ||
gte | {gte: ...} = greater than or equals. | ||
| TimeSeries | ❌ | Not supported. | |
| User defined type | ❌ | Not supported. | |
| Lists([XXX]) | ❌ | Not supported. |
Unit conversion
Fields that are enabled for unit conversion will contain targetUnit and targetUnitSystem attributes.
targetUnit: specifies the external ID of the unit that the retrieved data will be converted to.targetUnitSystem: specifies the unit by the unit system the retrieved data will be converted to.
See developer.cognite.com for more information and examples.
Unit information
unitInfo object contains unit information, unitExternalId, sourceUnit for unit enabled fields.
See developer.cognite.com for more information and examples.
Pagination in list and getById queries
GraphQL list and getById queries support cursoring. In list queries, you can cursor only at the top-level.
In getById queries, you can cursor only at the first sub-query level.
The hasNextPage field in pageInfo will under certain conditions be true even when there is not more data.
Specifically if the total number of items is divisible by first. You should therefore always exhaust
cursors until no items are returned, and not rely upon hasNextPage.
GraphQL list and getById queries with subqueries
GraphQL list and getById queries include subqueries on fields backed by direct relations or edges. When querying these fields, a maximum result set size of 10,000 items applies. This limit refers to the total number of items returned by a subquery, not per item in the parent subquery.
For example:
query ListActors {
listActors(first: 100) {
name
actedTogether(first: 10) {
items {
name
actedTogether(first: 15) {
items {
name
}
}
}
}
}
}
Here, Actors is a type with fields name and actedTogether, where actedTogether is an edge property.
- The root
listActorsquery returns up to 100 items. - The first nested
actedTogethersubquery has a limit of 10 items. - The second nested
actedTogethersubquery has a limit of 15 items.
If the dataset exceeds the subquery limits, the root query will still return 100 items, each item containing 10 actedTogether items, and each of those containing 15 more actedTogether items.
Thus, the total number of items returned in the actedTogether subquery would be:
100 (root) × 10 (actedTogether level 1) × 15 (actedTogether level 2) = 15,000 items
This exceeds the maximum allowed result set size of 10,000 items.
When the result set size limit is exceeded, any additional items beyond the limit will be excluded from the response.
Risks of using first in GraphQL subqueries
Cognite supports using the first parameter at the top-level in a "list" query and at the first subquery level of a "getById" query. The parameter limits the number of returned items, and you can use it in combination with a sort to pick the first/last items of a query. For other subqueries, first is allowed for legacy support, but shouldn't be used.
- In subqueries targeting a list of direct relations, or a reverse direct relation,
firstis allowed but not implemented. Supplying the parameter has no effect on the result. - In subqueries targeting edges,
firstis allowed and implemented, but isn't compatible withsort. The limit imposed byfirstis applied before the items are sorted.
Example of using first in a list query
In a list query, first is correctly applied if it's used at the top-level of the query, but not if it follows a list of direct relations or a reverse direct relation in a subquery.
For example:
query MyQuery {
listMovie(first: 1) {
items {
producers(first: 1) {
items {
name
}
}
}
}
}
In this example, "Movie" is a type with a "producers" field that's backed by either a list of direct relations or a reverse direct relation. The result of the top level list query "listMovie" will be correctly limited to a single result. The "producers" subquery, however, won't be limited.
Example output:
{
"listMovie": {
"items": [
{
"producers": {
"items": [
{
"name": "producer_1"
},
{
"name": "producer_0"
}
]
}
}
]
}
}
Example of using first in a getById query
In a getById query, you can use first at the first subquery level.
For example:
query MyQuery {
getMovieById(instances: {
space: "movies",
externalId: "movie_0"
}) {
items {
producers(first: 1) {
items {
externalId
}
}
}
}
}
Where "producers" could be a subquery targeting either a list of direct relations, a reverse direct relation, or an edge connection property.
Example output:
{
"getMovieById": {
"items": [
{
"producers": {
"items": [
{
"externalId": "producer_0"
}
]
}
}
]
}
}
However, you can't use first in further nested subqueries. For example, the following
query, where we use first for a nested subquery, "movies", won't work as expected:
query MyQuery {
getMovieById(instances: {
space: "movies",
externalId: "movie_0"
}) {
items {
producers(first: 1) {
items {
externalId
movies(first: 1) {
items {
externalId
}
}
}
}
}
}
}
The result of the "movies" subquery won't be limited to a single item. Example output:
{
"getMovieById": {
"items": [
{
"producers": {
"items": [
{
"externalId": "producer_0",
"movies": {
"items": [
{
"externalId": "movie_0"
},
{
"externalId": "movie_1"
}
]
}
}
]
}
}
]
}
}