Repeatable relationship path specification
TypeScript type: RepeatableRelationshipPathSpecification.
This specification declares a step in a relationship path between a source and target ECInstances. A step can optionally be repeated a number of times to traverse the same relationship recursively. Multiple specifications of this type can be chained together to express complex indirect relationships.
The specification is always used in a context where source class already exists, so it only requires the relationship and direction. The
target class can be inferred from the two required attributes or specified with the targetClass
attribute. In case of a
multi-step path, target of the current step is used as the source of the next step.
Attributes
Name | Required? | Type | Default |
---|---|---|---|
relationship |
Yes | SingleSchemaClassSpecification |
|
direction |
Yes | "Forward" | "Backward" |
|
targetClass |
No | SingleSchemaClassSpecification |
Other end of the relationship |
count |
No | number | "*" |
1 |
Attribute: relationship
This attribute specifies the ECRelationship that should be used to traverse to target class.
Type | SingleSchemaClassSpecification |
Is Required | Yes |
Attribute: direction
This attribute specifies the direction in which the relationship should be followed:
"Forward"
- the relationship is traversed from source to target of the relationship."Backward"
- the relationship is traversed from target to source of the relationship.
Type | "Forward" | "Backward" |
Is Required | Yes |
Attribute: targetClass
This attribute may be used to specialize the target of the relationship. E.g. when relationship points to a class like bis.Element
, this
attribute allows specializing it to bis.PhysicalElement
or some other bis.Element
subclass.
Type | SingleSchemaClassSpecification |
Is Required | No |
Default Value | Target ECClass of the relationship if the direction is "Forward" or source ECClass if the direction is "Backward" |
Attribute: count
When a number is specified, the relationship is traversed recursively the specified number of times.
When it is set to a special value "*"
, the same relationship is traversed recursively unbounded number of times, starting from zero (the relationship is not followed). On each traversal iteration, Presentation rules engine accumulates all indirectly related ECInstances as defined by the remaining relationship path.
Type | number | "*" |
Is Required | No |
Default Value | 1 |
Examples
When the count
attribute is omitted or set to 1
, the specification works similarly to RelationshipPathSpecification. See its examples section for those simpler cases.
Jumping through the same relationship recursively fixed number of times
// This ruleset defines a specification that returns content for given `bis.Element` instances by
// returning their grandparent property values.
const ruleset: Ruleset = {
id: "example",
rules: [{
ruleType: "Content",
condition: `SelectedNode.IsOfClass("Element", "BisCore")`,
specifications: [
{
specType: "ContentRelatedInstances",
relationshipPaths: [{
relationship: { schemaName: "BisCore", className: "ElementOwnsChildElements" },
direction: "Backward",
count: 2,
}],
},
],
}],
};
Jumping through the relationship recursively unbounded number of times
// This ruleset defines a specification that returns content for all children of the given `bis.Element`.
const ruleset: Ruleset = {
id: "example",
rules: [{
ruleType: "Content",
condition: `SelectedNode.IsOfClass("Element", "BisCore")`,
specifications: [
{
specType: "ContentRelatedInstances",
relationshipPaths: [{
relationship: { schemaName: "BisCore", className: "ElementOwnsChildElements" },
direction: "Forward",
count: "*",
}],
},
],
}],
};
When the root subject is provided as input, content for all its child elements is returned:
Combining recursive and non-recursive steps
// This ruleset defines a specification that returns content for categories of all elements in
// the given `bis.Model` and their children.
const ruleset: Ruleset = {
id: "example",
rules: [{
ruleType: "Content",
condition: `SelectedNode.IsOfClass("Model", "BisCore")`,
specifications: [
{
specType: "ContentRelatedInstances",
relationshipPaths: [[{
relationship: { schemaName: "BisCore", className: "ModelContainsElements" },
direction: "Forward",
targetClass: { schemaName: "BisCore", className: "GeometricElement3d" },
}, {
relationship: { schemaName: "BisCore", className: "ElementOwnsChildElements" },
direction: "Forward",
targetClass: { schemaName: "BisCore", className: "GeometricElement3d" },
count: "*",
}, {
relationship: { schemaName: "BisCore", className: "GeometricElement3dIsInCategory" },
direction: "Forward",
}]],
},
],
}],
};
When a physical model is provided as input, categories' content of all its elements and their children is returned:
Combining multiple unbounded recursive steps
// The ruleset contains a three-step relationship path that finds all `bis.GeometricElement3d` elements related to given model
// through the `bis.ModelContainsElements` relationship, then finds all `bis.SpatialCategory` elements related to `bis.GeometricElement3d`
// found in the previous step through `bis.GeometricElement3dIsInCategory` relationship and finds all `bis.SubCategory` elements related
// to `bis.SpatialCategory` found in the previous step through `bis.CategoryOwnsSubCategories` relationship.
// The result includes `bis.GeometricElement3d`, `bis.SpatialCategory` and `bis.SubCategory` elements.
const ruleset: Ruleset = {
id: "example",
rules: [{
ruleType: "Content",
condition: `SelectedNode.IsOfClass("Model", "BisCore")`,
specifications: [
{
specType: "ContentRelatedInstances",
relationshipPaths: [[{
relationship: { schemaName: "BisCore", className: "ModelContainsElements" },
direction: "Forward",
targetClass: { schemaName: "BisCore", className: "GeometricElement3d" },
count: "*",
}, {
relationship: { schemaName: "BisCore", className: "GeometricElement3dIsInCategory" },
direction: "Forward",
targetClass: { schemaName: "BisCore", className: "SpatialCategory" },
count: "*",
}, {
relationship: { schemaName: "BisCore", className: "CategoryOwnsSubCategories" },
direction: "Forward",
count: "*",
}]],
},
],
}],
};
Last Updated: 24 January, 2023