
This blog is about how to define Hierarchy View in CDS.
There are two types of hierarchies – 'Leveled Hierarchy' and 'Parent-Child Hierarchy' In Analytics, only a Parent-Child hierarchy is supported.
In CDS, Hierarchy can be defined in two ways:
In the past, External hierarchy was defined using the annotation '@ObjectModel.dataCategory: #HIERARCHY'. Now, in CDS it is allowed to define new type of CDS view called as Hierarchy CDS, which is defined using syntax define hierarchy, which create a hierarchical view.
A CDS hierarchy represents a HANA hierarchy, created when the CDS hierarchy is activated.
Normally the hierarchy contains headers and nodes. The header data of the hierarchy is coming from the directory view and the nodes data is coming from the hierarchy view itself.
Hierarchy Directory
The directory of the hierarchy provides the header information of the hierarchy. A hierarchy view might contain more than one hierarchy. Information about each hierarchy (e.g. text) is provided by a hierarchy directory. More information can be found in blog.
Typically, the directory view is defined as follows:
@EndUserText.label: 'Connection Hierarchy Directory View'
@Analytics : { dataCategory: #DIMENSION, dataExtraction.enabled: true }
@ObjectModel.representativeKey: 'hieid'
define view entity ZLR_CONNECTION_HIERARCHY_DIR
as select from zoq_connid_hd
{
@ObjectModel.text.element: [ 'hiertxt' ]
key hieid,
@Semantics.text: true
hiertxt,
@Semantics.systemDate.lastChangedAt: true
last_changed,
}
Output
Hierarchy View using define hierarchy <NAME>
This is the new way of defining hierarchy and it is available from 2023 on Prem and 2308 Cloud. For defining hierarchy, prerequisite is having a source view, which is mentioned in the definition as parent child hierarchy source.
Source View
In view definition parent child association is define along with that following associations:
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'Base for : New Way of defining Hierarchy'
define view entity ZLR_CONN_HIERARCHY_BASE
as select from zoq_connid_h
//association to itself.
association [0..1] to ZLR_CONN_HIERARCHY_BASE as _parent on $projection.hieid = _parent.hieid
and $projection.parentid = _parent.nodeid
// association with hierarchy directory
association [1] to ZLR_CONNECTION_HIERARCHY_DIR as _dir on $projection.hieid = _dir.hieid
// associations to the different node types
// evalulated at runtime for each record in the order given here
// first hit of ON-condition is followed
// Differnce to old way of Hierarchy ZLR_CONNECTION_HIERARCHY - here no $projection.carrid = '' and $projection.connid = '0000'
association [1] to ZOQ_CONNECTION_NODENAME as _node on $projection.hieid = _node.hieid
and $projection.nodename = _node.nodeName
// "nodatetype" Airline
// Differnce to old way of Hierarchy ZLR_CONNECTION_HIERARCHY - here no and $projection.connid = '0000'
association [1] to ZOQ_AIRLINE as _airline on $projection.carrid = _airline.carrid
// association to dimension view
association [1] to ZLR_CONN as _connection on $projection.carrid = _connection.carrid
and $projection.connid = _connection.connid
{
@Consumption.filter: { mandatory : true, selectionType : #SINGLE, multipleSelections : false }
@ObjectModel.foreignKey.association: '_dir'
key hieid,
key nodeid,
parentid,
seqno,
// three different node types possible in this example
// here CONNID is leaf (can not be derived from this view)
@ObjectModel.foreignKey.association: '_airline'
carrid,
@ObjectModel.foreignKey.association: '_connection'
connid,
@ObjectModel.foreignKey.association: '_node'
nodename,
cast(
case when carrid is initial and connid is initial then 'NODENAME'
when connid is initial then 'CARRID'
else 'CONNID' end as fieldname ) as nodetype,
// associations defined above have to be exposed here
// otherwise they will not be available
_parent,
_dir,
_node,
_airline,
_connection
}
Hierarchy View
Hierarchy view can be defined using the following syntax.
Syntax:
In Syntax
source
ZLR_CONN_HIERARCHY_BASE
child to parent association
_parent
OR
period from datefrom to dateto valid from '20230425' to '20230425'
_dir filter by hienm = $parameters.p_hienm1
and keydate = $parameters.p_keydate
start where
parentid is initial
siblings order by
seqno
In context of Analytics, it is mandatory to define the nodetype field in the source view of the hierarchy and also in the hierarchy view using key word 'nodetype'
For example, in the Source view
cast(
case when carrid is initial and connid is initial then 'NODENAME'
when connid is initial then 'CARRID'
else 'CONNID' end as fieldname ) as nodetype,
In the Hierarchy view
nodetype
nodetype
More detailed information can be found here ABAP Keyword Documentation (sap.com).
Example of Hierarchy View
define hierarchy ZLR_CONN_HIERARCHY
with parameters
@Consumption.defaultValue: 'CNTRY'
p_hieid : zoq_conhieid
as parent child hierarchy(
source ZLR_CONN_HIERARCHY_BASE
child to parent association _parent
directory _dir filter by
hieid = $parameters.p_hieid
start where
parentid is initial
siblings order by
seqno
nodetype nodetype
)
{
@ObjectModel.foreignKey.association: '_dir'
key hieid,
key nodeid,
parentid,
seqno,
@ObjectModel.foreignKey.association: '_airline'
carrid,
@ObjectModel.foreignKey.association: '_connection'
connid,
@ObjectModel.foreignKey.association: '_node'
nodename,
nodetype,
// associations defined above have to be exposed here
// otherwise they will not be available
_parent,
_dir,
_node,
_airline,
_connection
}
Output
Red: association _node
Green: association _airline
Blue: association _connection, the blue marked records are leaves
Example of Query using Hierarchy
@AccessControl.authorizationCheck: #NOT_ALLOWED
@EndUserText.label: 'ZLR_CONN - query'
@Metadata.ignorePropagatedAnnotations: true
define transient view entity ZLR_CONN_QUERY
provider contract analytical_query
as projection on ZLR_CONN
{
@AnalyticsDetails.query:{
axis:#ROWS,
displayHierarchy: #ON ,
hierarchyBinding: [{ type: #CONSTANT, value: 'CNTRY' }]
}
connid
}
Output
Hierarchy View Using @ObjectModel.dataCategory: #HIERARCHY Annotation (OLD way)
In View definition the annotation @Hierarchy.parentChild provides the information about the parent child hierarchy. It has hierarchy name, multiple parents, recursion by, ordering of siblings, root node visibility, orphaned node handling, etc. along with that, following associations need to be defined.
Important is the order of the associations listed in the element-list and the 'extra-condition' in the ON-clause. For each record of the hierarchy the ON condition of the associations is checked - the first association which meets the ON condition is used to get text and attributes for the hierarchy node/leaf.
One association is mandatory - its target must be the dimension view which has a ObjectModel.hierarchy.association to the hierarchy view. These objects in the hierarchy represent the leaves.
Example
@EndUserText.label: 'Connection Hierarchy View'
@ObjectModel.dataCategory: #HIERARCHY
@Hierarchy.parentChild: [{
name : 'ConnectionHierarchy',
label : 'Connection',
siblingsOrder: [{ by: 'seqno' }] ,
recurseBy : '_parent',
directory: '_dir'
}]
define view entity ZLR_CONNECTION_HIERARCHY
as select from zoq_connid_h
// basic parent child relation inside one hierarchy
// hierarchy uniquely selected (see @Filter for field HIEID
association [0..1] to ZLR_CONNECTION_HIERARCHY as _parent on $projection.parentid = _parent.nodeid
// necessary if view represents several hierarchies
// association to the hierarchy directory
association [1] to ZLR_CONNECTION_HIERARCHY_DIR as _dir on $projection.hieid = _dir.hieid
// associations to the different node types
// evalulated at runtime for each record in the order given here
// first hit of ON-condition is followed
association [1] to ZOQ_CONNECTION_NODENAME as _node on $projection.hieid = _node.hieid
and $projection.nodename = _node.nodeName
and $projection.carrid = ''
and $projection.connid = '0000'
// "nodatetype" Airline
association [1] to ZOQ_AIRLINE as _airline on $projection.carrid = _airline.carrid
and $projection.connid = '0000'
// For which dimension this hierarchy belongs
association [1] to ZLR_CONNECTION as _connection on $projection.carrid = _connection.carrid
and $projection.connid = _connection.connid
{
@Consumption.filter: { mandatory : true, selectionType : #SINGLE, multipleSelections : false }
@ObjectModel.foreignKey.association: '_dir'
key hieid,
key nodeid,
parentid,
seqno,
// three different node types possible in this example
// here CONNID is leaf (can not be derived from this view)
@ObjectModel.foreignKey.association: '_airline'
carrid,
@ObjectModel.foreignKey.association: '_connection'
connid,
@ObjectModel.foreignKey.association: '_node'
nodename,
// associations defined above have to be exposed here
// otherwise they will not be available
_parent,
_dir,
_node,
_airline,
_connection
}
Output
Red: association _node
Green: association _airline
Blue: association _connection, the blue marked records are leaves
Reference
More information on @Semantics.signReversalIndicator can be found in the blog.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
User | Count |
---|---|
17 | |
16 | |
12 | |
12 | |
10 | |
9 | |
7 | |
6 | |
6 | |
5 |