Dynamic hierarchies
- Last UpdatedAug 11, 2026
- 3 minute read
Dynamic hierarchies allow you to define and manage structured, multi-level entity navigation views for the Explore page. They provide a flexible, intuitive way to explore entities without relying on static queries. Users can choose from a set of hierarchy definitions, each built from multi-level GraphQL queries, that determine how entities appear and can be navigated.
Why use the Hierarchy API?
-
Flexible exploration of entities
Each hierarchy is a dynamic, configurable set of ordered queries that determine:
-
Which entities appear at each hierarchy level.
-
How users traverse from one level to the next.
-
How relationships are filtered and applied.
This makes the Explore page more expressive and adaptable to different data models.
-
-
Support for complex, multi-level structures
Hierarchies can include multiple levels, each defined by its own GraphQL query. This allows you to create advanced navigation patterns like:
-
Server → Database → Table
-
Device → Component → Subcomponent
-
Facility → Area → Equipment → Sensors
You can also enable recursive expansion of the last level for deep relationship chains by setting the leafLevelIsRecursive property as true.
-
-
Ensured data integrity through validation
Each hierarchy query undergoes validation.
-
Validation for GraphQL syntax correctness as per the Knowledge Graph schema version.
-
Validation that GraphQL queries do not include nested selection sets; users will only be allowed to select fields directly from entities.
-
Only entity queries are allowed. Users won’t be able to query other types like events and types.
-
Presence of at least one entity relationship filter from level 2+. Since every node represents an entity in the graph, each query from the second level onwards must include at least one relationship filter with targetBase as ENTITY to ensure meaningful traversal.
-
Maximum hierarchy depth of 16.
-
Additional validations to keep the hierarchy traversal straightforward for the UI:
-
Queries should only have arguments from the second query onwards.
-
IDs (string array) is the only argument allowed, and these IDs should be used exclusively with relationship values.
This ensures queries remain predictable, secure, and compatible with UI traversal logic.
-
-
V3 and V4-preview routes enforce validation to ensure that the selection set includes the required fields: id, name and className.
-
Below is an example of a valid GraphQL query with required fields included in the selection set: "query {entities(input: {filter: { where: { components: [{ typeId: \"BaseAsset\" }]}}}) { items { id name className }}}"
-
The V4-preview hierarchy route introduces enhancements to support multi-schema compatibility and improved validation visibility.
Schema compatibility support:
-
CompatibleSchemaVersions is included in the hierarchy response. This property lists all Knowledge Graph schema versions for which the hierarchy definition has been validated and is compatible with.
-
ValidationState is returned as part of the warnings to provide detailed validation error state. It includes:
Schema versions where the hierarchy is not compatible.
Associated validation errors explaining the incompatibility. This enables consumers to better understand and troubleshoot validation issues across schema versions.
Deprecation: The knowledgeGraphSchemaVersion property is deprecated in both the request and response payloads.
-
-
The Hierarchy API lets you:
-
Create and store custom hierarchies.
-
Edit and manage existing hierarchies.
-
Secure hierarchies with security tags.
-
Retrieve and display hierarchies in UI experiences.
-
Delete outdated hierarchies.
Example hierarchy for V3 route POST request:
{
"id": "PI.AF.Hierarchy",
"name": "PI AF Hierarchy",
"description": "Common and default hierarchy from PI Asset Framework via PI to CONNECT Agent",
"knowledgeGraphSchemaVersion": "V3",
"leafLevelIsRecursive": true,
"tags": ["PI.AF.Hierarchy" ],
"hierarchyLevels": [
{
"query": "query {entities(input: {filter: { where: { components: [{ typeId: \"PI.AF.Server\" }]}}}) { items { id name className }}}"
},
{
"query": "query($Ids: [String]!) {entities(input: {filter: {where: { components: [{ typeId: \"PI.AF.Database\", relationships:[{ values: $Ids, id:\"IsHostedBy\", targetBase: ENTITY }] }]}}}) {items { id name className }}}"
},
{
"query": "query($Ids: [String]!) {entities(input: {filter: {where: { components: [{ typeId: \"PI.AF.Element.Child\", relationships:[{ values: $Ids, id:\"IsPrimarilyAChildOf\", targetBase: ENTITY }] }]}}}) {items { id name className }}}"
}
]
}
Example hierarchy for V4-preview route POST request:
{
"id": "PI.AF.Hierarchy",
"name": "PI AF Hierarchy",
"description": "Common and default hierarchy from PI Asset Framework via PI to CONNECT Agent",
"leafLevelIsRecursive": true,
"tags": ["PI.AF.Hierarchy" ],
"hierarchyLevels": [
{
"query": "query {entities(input: {filter: { where: { components: [{ typeId: \"PI.AF.Server\" }]}}}) { items { id name className }}}"
},
{
"query": "query($Ids: [String]!) {entities(input: {filter: {where: { components: [{ typeId: \"PI.AF.Database\", relationships:[{ values: $Ids, id:\"IsHostedBy\", targetBase: ENTITY }] }]}}}) {items { id name className }}}"
},
{
"query": "query($Ids: [String]!) {entities(input: {filter: {where: { components: [{ typeId: \"PI.AF.Element.Child\", relationships:[{ values: $Ids, id:\"IsPrimarilyAChildOf\", targetBase: ENTITY }] }]}}}) {items { id name className }}}"
}
]
}