Retrieve
API Approaches
OctoMesh provides two ways to query entities:
| Approach | Endpoint | Use Case |
|---|---|---|
| Typed | runtime.[typeName] | Strongly typed, IDE autocompletion, compile-time validation |
| Generic | runtime.runtimeEntities | Dynamic type handling, flexible attribute access |
Typed Query (Simple query)
The area runtime allows access to entities fo the Runtime Model Let's start with simple sample that requests customers of energy communities and return the runtime identifier (rtId), construction kit type identifier (ckTypeId) and the contact data of all customers.
query {
runtime {
energyCommunityCustomer {
items {
rtId
ckTypeId
contact{
companyName
firstName
lastName
}
}
}
}
}
The result of that query
{
"data": {
"runtime": {
"energyCommunityCustomer": {
"items": [
{
"rtId": "693c4cd3464d7d9e1396cf0d",
"ckTypeId": "EnergyCommunity/Customer",
"contact": {
"companyName": null,
"firstName": "John",
"lastName": "Doe"
}
},
{
"rtId": "693c4d97464d7d9e1396cf10",
"ckTypeId": "EnergyCommunity/Customer",
"contact": {
"companyName": null,
"firstName": "Jane",
"lastName": "Smith"
}
}
]
}
}
}
}
This query has some disadvantages. The amount of objects returned depends on the amount of objects stored. The next sample uses pagination to limit the amount of objects returned.
Generic Query
The generic runtimeEntities endpoint allows querying entities of any type dynamically. This is useful when the type is not known at compile time or when building dynamic applications.
Basic Generic Query
query {
runtime {
runtimeEntities(ckTypeId: "OctoSdkDemo/Customer", first: 10) {
items {
rtId
ckTypeId
rtWellKnownName
rtCreationDateTime
rtChangedDateTime
attributes(first: 20) {
items {
attributeName
value
}
}
}
}
}
}
Response:
{
"data": {
"runtime": {
"runtimeEntities": {
"items": [
{
"rtId": "693c5b93464d7d9e1396cf1c",
"ckTypeId": "OctoSdkDemo/Customer",
"rtWellKnownName": "customer-001",
"rtCreationDateTime": "2024-01-15T10:30:00Z",
"rtChangedDateTime": "2024-01-20T14:00:00Z",
"attributes": {
"items": [
{ "attributeName": "customerStatus", "value": 1 },
{ "attributeName": "dateOfBirth", "value": "1985-03-15T00:00:00Z" },
{ "attributeName": "contact", "value": { "firstName": "John", "lastName": "Doe" } }
]
}
}
]
}
}
}
}
RtEntity Type Fields
The generic RtEntity type provides the following fields:
| Field | Type | Description |
|---|---|---|
rtId | OctoObjectId! | Unique runtime identifier |
ckTypeId | RtCkId! | Construction Kit type identifier |
rtWellKnownName | String | Optional well-known name |
rtCreationDateTime | DateTime | Creation timestamp |
rtChangedDateTime | DateTime | Last modification timestamp |
rtVersion | Int | Entity version number |
attributes | Connection | Generic attribute access with filtering |
associations | RtEntityGenericAssociation | Generic association access |
Filtering Attributes
The attributes field supports filtering by attribute names:
query {
runtime {
runtimeEntities(ckTypeId: "OctoSdkDemo/Customer", first: 10) {
items {
rtId
# Only retrieve specific attributes
attributes(
first: 10
attributeNames: ["customerStatus", "contact", "dateOfBirth"]
) {
items {
attributeName
value
}
}
}
}
}
}
Resolving Enum Values to Names
By default, enum values are returned as integers. Use resolveEnumValuesToNames: true to get human-readable names:
query {
runtime {
runtimeEntities(ckTypeId: "OctoSdkDemo/Customer", first: 10) {
items {
rtId
attributes(first: 10, resolveEnumValuesToNames: true) {
items {
attributeName
value
}
}
}
}
}
}
Without resolveEnumValuesToNames:
{ "attributeName": "customerStatus", "value": 1 }
With resolveEnumValuesToNames: true:
{ "attributeName": "customerStatus", "value": "ACTIVE" }
Generic Associations
The generic associations field provides two connections for querying related entities:
Targets Connection
The targets connection retrieves related entities (association targets):
query {
runtime {
runtimeEntities(ckTypeId: "OctoSdkDemo/MeteringPoint", first: 10) {
items {
rtId
associations {
targets(
roleId: "parent"
direction: OUTBOUND
ckId: "OctoSdkDemo/Customer"
first: 10
) {
items {
rtId
ckTypeId
attributes(first: 5) {
items {
attributeName
value
}
}
}
}
}
}
}
}
}
Targets Arguments:
| Argument | Type | Required | Description |
|---|---|---|---|
roleId | String! | Yes | The role id of the association |
direction | GraphDirection! | Yes | INBOUND or OUTBOUND |
ckId | String! | Yes | The construction kit type id of the target |
includeIndirect | Boolean | No | Include indirect associations (default: false) |
searchFilter | SearchFilter | No | Full-text search filter |
fieldFilter | [FieldFilter] | No | Field-based filters |
sortOrder | [Sort] | No | Sort order for results |
aggregations | ResultAggregation | No | Aggregation options |
Definitions Connection
The definitions connection retrieves association metadata (the association records themselves):
query {
runtime {
runtimeEntities(ckTypeId: "OctoSdkDemo/MeteringPoint", first: 10) {
items {
rtId
associations {
definitions(
direction: OUTBOUND
roleId: "parent"
first: 10
) {
items {
roleId
rtTargetId
ckTargetId
}
}
}
}
}
}
}
Definitions Arguments:
| Argument | Type | Required | Description |
|---|---|---|---|
direction | GraphDirection! | Yes | INBOUND or OUTBOUND |
roleId | String | No | Filter by association role id |
relatedRtCkId | RtCkId | No | Filter by target type id |
relatedRtId | OctoObjectId | No | Filter by target entity id |
Query by rtId with Generic API
query {
runtime {
runtimeEntities(rtIds: ["693c5b93464d7d9e1396cf1c", "693c5b93464d7d9e1396cf1d"]) {
items {
rtId
ckTypeId
attributes(first: 20) {
items {
attributeName
value
}
}
}
}
}
}
Pagination
query {
runtime {
energyCommunityCustomer(first: 1) {
pageInfo {
endCursor
startCursor
}
items {
rtId
ckTypeId
contact {
companyName
firstName
lastName
}
}
}
}
}
This query uses an argument first that limits the result to 1. We use pageInfo to retrieve the start and end cursor to continue pagination.
{
"data": {
"runtime": {
"energyCommunityCustomer": {
"pageInfo": {
"endCursor": "YXJyYXljb25uZWN0aW9uOjA=",
"startCursor": "YXJyYXljb25uZWN0aW9uOjA="
},
"items": [
{
"rtId": "693c4cd3464d7d9e1396cf0d",
"ckTypeId": "EnergyCommunity/Customer",
"contact": {
"companyName": null,
"firstName": "John",
"lastName": "Doe"
}
}
]
}
}
}
}
The end cursor can be used for the next pagination:
query {
runtime {
energyCommunityCustomer(first: 1, after:"YXJyYXljb25uZWN0aW9uOjA=") {
pageInfo {
endCursor
startCursor
}
items {
rtId
ckTypeId
contact {
companyName
firstName
lastName
}
}
}
}
}
The result will be the next page:
{
"data": {
"runtime": {
"energyCommunityCustomer": {
"pageInfo": {
"endCursor": "YXJyYXljb25uZWN0aW9uOjE=",
"startCursor": "YXJyYXljb25uZWN0aW9uOjE="
},
"items": [
{
"rtId": "693c4d3e464d7d9e1396cf0e",
"ckTypeId": "EnergyCommunity/Customer",
"contact": {
"companyName": null,
"firstName": "John",
"lastName": "Doe"
}
}
]
}
}
}
}
Query options
The options parameter allows you to control query behavior. By default, archived entities are excluded from query results.
| Option | Type | Default | Description |
|---|---|---|---|
includeArchivedEntities | Boolean | false | Include entities that have been archived (soft deleted) |
Include archived entities
To include archived entities in the query results:
query {
runtime {
energyCommunityCustomer(options: { includeArchivedEntities: true }) {
items {
rtId
ckTypeId
contact {
companyName
firstName
lastName
}
}
}
}
}
This is useful when you need to view or restore previously deleted data. See Delete for more information about archiving entities.
Filter options
There are different types of filters available to request data based on specific conditions. Filters can be combined in a single query.
| Filter Type | Description | Documentation |
|---|---|---|
rtId / rtIds | Filter by runtime identifier(s) | See below |
fieldFilter | Filter by attribute conditions | See below |
searchFilter | Full-text search across attributes | SearchFilter |
geoNearFilter | Geospatial filtering | See below |
RtId filter
The rtId filter allows to request data based on the runtime identifier. The type of argument rtId is a runtime identifier, the type of argument rtIds is an array of runtime identifiers.
query {
runtime {
energyCommunityCustomer(rtId: "693c4d3e464d7d9e1396cf0e") {
items {
rtId
ckTypeId
contact {
companyName
firstName
lastName
}
}
}
}
}
The result will be the energy meter with the runtime identifier "6628101bf163c7c8f8676a33".
{
"data": {
"runtime": {
"energyCommunityCustomer": {
"items": [
{
"rtId": "693c4d3e464d7d9e1396cf0e",
"ckTypeId": "EnergyCommunity/Customer",
"contact": {
"companyName": null,
"firstName": "John",
"lastName": "Doe"
}
}
]
}
}
}
}
Field filters
Field filters allow to request data based on specific conditions of different fields. Multiple field filters are combined using the AND logical operator.
For a complete list of available filter operators, see Overview.
query {
runtime {
energyCommunityCustomer(fieldFilter:[{attributePath:"contact.lastName", operator:EQUALS, comparisonValue:"Doe"}]) {
items {
rtId
ckTypeId
contact {
companyName
firstName
lastName
}
}
}
}
}
geoNear filter
geoNear filter allow to filter for data from nearest to farthest on a geospatial point. The type of argument geoNearFilter is a complex object to configure the filter.
| Property | Description |
|---|---|
| attributeName | The attribute name that represents a geospatial point |
| minDistance | Minimal distance from point to filter for data in meter |
| maxDistance | Maximal distance from point to filter for data in meter |
| point | A point that specifies a point. |
query getFireReports($position:PositionInput!, $minDistance:Float, $maxDistance:Float) {
runtime {
fireGuardiansFireReport(
first: 200,
geoNearFilter: {
attributeName: "location"
minDistance: $minDistance
maxDistance: $maxDistance
point: { coordinates: $position }
}
) {
items {
rtId
rtCreationDateTime
name
description
location {
distance
point {
coordinates {
latitude
longitude
}
}
}
}
}
}
}
Geospatial data types contains a field that describes, when geoNear filter is used, the distance in meter from the in the filter specified point.
{
"data": {
"runtime": {
"fireGuardiansFireReport": {
"items": [
{
"rtId": "65d5c447b420da3fb12381b9",
"rtCreationDateTime": "2022-02-22T09:00:00Z",
"name": "FireReport1",
"description": "FireReport1",
"location": {
"distance": 4508,
"point": {
"coordinates": {
"latitude": 48.123456,
"longitude": 11.123456
}
}
}
}
]
}
}
}
}
Sort order
The default sort order is based on the rtId. The sort order can be changed using the argument sortOrder. The argument is an array of objects containing the attribute path and sort direction.
For available sort order values, see Overview.
Sample to sort the energy meters by name in ascending order:
query {
runtime {
energyCommunityCustomer(sortOrder:[{attributePath:"contact.firstName", sortOrder: DESCENDING}]) {
items {
rtId
ckTypeId
contact {
companyName
firstName
lastName
}
}
}
}
}
The result will be sorted by the name in ascending order.
{
"data": {
"runtime": {
"energyCommunityCustomer": {
"items": [
{
"rtId": "693c4cd3464d7d9e1396cf0d",
"ckTypeId": "EnergyCommunity/Customer",
"contact": {
"companyName": null,
"firstName": "John",
"lastName": "Doe"
}
},
{
"rtId": "693c4d3e464d7d9e1396cf0e",
"ckTypeId": "EnergyCommunity/Customer",
"contact": {
"companyName": null,
"firstName": "John",
"lastName": "Doe"
}
},
{
"rtId": "693c4d97464d7d9e1396cf0f",
"ckTypeId": "EnergyCommunity/Customer",
"contact": {
"companyName": null,
"firstName": "John",
"lastName": "Doe"
}
},
{
"rtId": "693c4d97464d7d9e1396cf10",
"ckTypeId": "EnergyCommunity/Customer",
"contact": {
"companyName": null,
"firstName": "Jane",
"lastName": "Smith"
}
}
]
}
}
}
}
Aggregations
There are two types of aggregations available: Aggregation based on the entire result set completely or use of grouping based aggregations.
Aggregations on result set
The type of argument aggregations is a complex object that allows to configure different types of aggregations based on the entire result set.
| field | Description |
|---|---|
| minValueAttributePaths | List of attribute paths the min value within the group is applied |
| maxValueAttributePaths | List of attribute paths the max value within the group is applied |
| countAttributePaths | List of attribute paths the values not null are counted |
| avgAttributePaths | List of attribute paths the average value within the group is applied |
query {
runtime {
energyCommunityCustomer(
aggregations: {
maxValueAttributePaths: ["contact.address.zipcode"]
}
) {
totalCount
aggregation{
count
maxStatistics{
attributePath
value
}
}
}
}
}
The result will contain the maximum zipcode of all customers.
{
"data": {
"runtime": {
"energyCommunityCustomer": {
"totalCount": 9,
"aggregation": {
"count": 9,
"maxStatistics": [
{
"attributePath": "contact.address.zipcode",
"value": 80331
}
]
}
}
}
}
}
Aggregations on result set with grouping
Grouping allows to group data based on fields. The type of argument groupBy is a complex object that allows to group by multiple fields and the type of aggregation.
| field | Description |
|---|---|
| aggregations.groupBy.groupByAttributePaths | List of attribute paths the grouping is applied |
| minValueAttributePaths | List of attribute paths the min value within the group is applied |
| maxValueAttributePaths | List of attribute paths the max value within the group is applied |
| countAttributePaths | List of attribute paths the values not null are counted |
| avgAttributePaths | List of attribute paths the average value within the group is applied |
The next sample groups the customers by state and retrieves the max zipcode within each state.
query {
runtime {
energyCommunityCustomer(
aggregations: {
groupBy: {
groupByAttributePaths: ["state"]
maxValueAttributePaths: ["contact.address.zipcode"]
}
}
) {
totalCount
fieldAggregations{
count
keys
maxStatistics{
attributePath
value
}
}
}
}
}
The result will be grouped by the state and the maximum zipcode within each state.
{
"data": {
"runtime": {
"energyCommunityCustomer": {
"totalCount": 9,
"fieldAggregations": [
{
"count": 7,
"keys": [
1
],
"maxStatistics": [
{
"attributePath": "contact.address.zipcode",
"value": 67890
}
]
},
{
"count": 2,
"keys": [
2
],
"maxStatistics": [
{
"attributePath": "contact.address.zipcode",
"value": 80331
}
]
}
]
}
}
}
}
Associations
Associations allow navigating relationships between entities. For detailed documentation, see Associations.
Navigation properties
The simplest way to access associations is through typed navigation properties:
query
{
runtime{
energyCommunityCustomer(rtId: "693c4cd3464d7d9e1396cf0d"){
items{
rtId
facilities{
energyCommunityOperatingFacility{
items{
rtId
name
}
}
}
}
}
}
}
The result will contain the associated operating facilities of the customer.
{
"data": {
"runtime": {
"energyCommunityCustomer": {
"items": [
{
"rtId": "693c4cd3464d7d9e1396cf0d",
"facilities": {
"energyCommunityOperatingFacility": {
"items": [
{
"rtId": "693c5b93464d7d9e1396cf1c",
"name": "Demo"
}
]
}
}
}
]
}
}
}
}
Generic associations query
For dynamic filtering by role, direction, or target type:
query
{
runtime{
energyCommunityCustomer(rtId: "693c4cd3464d7d9e1396cf0d"){
items{
rtId
associations(
roleId: "EnergyCommunity/AssociatedCustomer"
direction: INBOUND
ckId: "EnergyCommunity/OperatingFacility"
includeIndirect: true
){
items{
rtId
ckTypeId
}
}
}
}
}
}
The result will contain the associated operating facilities of the customer.
{
"data": {
"runtime": {
"energyCommunityCustomer": {
"items": [
{
"rtId": "693c4cd3464d7d9e1396cf0d",
"associations": {
"items": [
{
"rtId": "693c5b93464d7d9e1396cf1c",
"ckTypeId": "EnergyCommunity/OperatingFacility"
}
]
}
}
]
}
}
}
}
See Associations for more examples including direction filtering, indirect associations, and association definitions.