Skip to main content

Celonis Product Documentation

LINK_PATH
Description

Warning

To use this feature, Object Link needs to be configured with Object Link in the data model.

The LINK_PATH operator creates an internal activity and case table to represent individual paths calculated by traversing the Object Link graph. The resulting activity table is joined towards the input table and to the internal case table in a N:1 fashion. Additional tables containing link attributes are generated and can be accessed via the LINK_PATH_SOURCE/TARGET operators.

Warning

In some settings, this operator may require excessive CPU time. If the execution time exceeds 10 minutes, the execution is stopped and an error is reported.

The output of LINK_PATH is a column containing all objects of all calculated paths, where each row's data corresponds to the value of the object in the input column. If only individual objects are of interest and a complete path is not required, use LINK_SOURCE/LINK_TARGET instead. As the generated tables are joined to the input table, all objects, as specified in the Object Link mapping table, must reside within this one table in order to avoid join cycles in the data model.

Syntax
 LINK_PATH ( input_table.column [, direction ] [, CONSTRAINED BY ( [ START ( start_objects_expression ) ] [, END ( end_objects_expression ) ] [, LENGTH ( comparison length ) ] ) ] )
  • LINK_PATH acquires object attributes from the specified input_table.column. Therefore, all objects, as they are specified in the Object Link mapping table, must be contained in this table.

  • direction specifies the traversal direction. Valid values for the parameter are FORWARDS (default) and BACKWARDS.

  • The graph traversal can further be CONSTRAINED BY:

    • start_objects_expression is a condition to specify the start objects of the graph traversal.

    • end_objects_expression is a condition to specify the end objects of the graph traversal.

    • comparison is one of = (equal), != (not equal), <> (not equal), < (less than), <= (less than or equal), >(greater than) or >= (greater than or equal). In conjunction with length, which is a positive integer, this can be used to specify the desired path lengths (as measured by the number of objects).

Syntax

Warning

Deprecated. Please use the previous syntax instead.

 PATH( input_table.column [, FILTER start_objects_expression ] [, FILTER end_objects_expression ] [, direction ])
  • The input_table must contain all objects specified in the Object Link mapping table.

  • The start_objects_expression and end_objects_expression parameters are common FILTER conditions.

  • Valid values for the direction parameter are FORWARDS (default) and BACKWARDS.

NULL handling
  • Object Link mapping table entries with NULL values in the OUT column are ignored.

  • Object Link mapping table entries with NULL values in the IN column will register the object specified in the OUT column. However, no link will be added to the Object Link graph.

Examples

[1]

LINK_PATH calculates, based on the mapping table, all possible paths from any start object to any end object. If no START or END parameter is provided to specify these objects, they are deduced from the Object Link graph. Default start objects do not possess incoming links whereas default end objects do not possess outgoing links. Entries of the input object table that are not mentioned in the mapping table are not legitimate objects for the Object Link graph and are thereby ignored.

Object_Link_Acyclic_Scenario.png

LINK_PATH calculates, based on the mapping table, all possible paths from any start object to any end object. If no START or END parameter is provided to specify these objects, they are deduced from the Object Link graph. Default start objects do not possess incoming links whereas default end objects do not possess outgoing links. Entries of the input object table that are not mentioned in the mapping table are not legitimate objects for the Object Link graph and are thereby ignored.

Query

Column1

         CASE_ID_COLUMN ( LINK_PATH ( "Case"."ID" ) )
        

Column2

         LINK_PATH ( "Case"."ID" )
        

Column3

         LINK_PATH ( "Case"."NODE_ATTR" )
        

Input

Output

Case

ID : string

NODE_ATTR : int

'A'

0

'B'

1

'C'

2

'D'

3

'E'

3

'F'

4

'G'

4

'H'

4

'J'

null

MAPPING

OUT : string

IN : string

'A'

null

'B'

'C'

'C'

'D'

'C'

'E'

'D'

'F'

'D'

'G'

'E'

'G'

'E'

'H'

'F'

'G'

Result

Column1 : int

Column2 : string

Column3 : int

0

'A'

0

1

'B'

1

1

'C'

2

1

'D'

3

1

'F'

4

1

'G'

4

2

'B'

1

2

'C'

2

2

'D'

3

2

'G'

4

3

'B'

1

3

'C'

2

3

'E'

3

3

'G'

4

4

'B'

1

4

'C'

2

4

'E'

3

4

'H'

4

[2]

Since LINK_PATH generates a new activity table, it also provides a case table where each case corresponds to one specific path within the Object Link graph. This example shows how to use the generated tables with Process and PU-functions to aggregate object information on a path level.

Query

Column1

         CASE_TABLE(LINK_PATH("Case"."ID"))."PATH_ID"
        

Column2

         VARIANT ( LINK_PATH ( "Case"."ID" ) )
        

Column3

         PU_COUNT ( CASE_TABLE ( LINK_PATH ( "Case"."ID" ) ) , LINK_PATH ( "Case"."ID" ) )
        

Input

Output

Case

ID : string

NODE_ATTR : int

'A'

0

'B'

1

'C'

2

'D'

3

'E'

3

'F'

4

'G'

4

'H'

4

'J'

null

MAPPING

OUT : string

IN : string

'A'

null

'B'

'C'

'C'

'D'

'C'

'E'

'D'

'F'

'D'

'G'

'E'

'G'

'E'

'H'

'F'

'G'

Result

Column1 : int

Column2 : string

Column3 : int

0

'A'

1

1

'B, C, D, F, G'

5

2

'B, C, D, G'

4

3

'B, C, E, G'

4

4

'B, C, E, H'

4

[3]

We can limit the traversal on more interesting objects by specifying conditions for the START and END objects respectively. Arbitrarily complex conditions can be used to select these objects. Note that for each unique combination of constraints, a new activity and case table is generated.

Query

Column1

         CASE_TABLE ( LINK_PATH ( "Case"."ID" , CONSTRAINED BY ( START ( "Case"."ID" IN ( 'C' ) ) , END ( "Case"."NODE_ATTR" = 4 ) ) ) ) ."PATH_ID"
        

Column2

         VARIANT ( LINK_PATH ( "Case"."ID" , CONSTRAINED BY ( START ( "Case"."ID" IN ( 'C' ) ) , END ( "Case"."NODE_ATTR" = 4 ) ) ) )
        

Input

Output

Case

ID : string

NODE_ATTR : int

'A'

0

'B'

1

'C'

2

'D'

3

'E'

3

'F'

4

'G'

4

'H'

4

'J'

null

MAPPING

OUT : string

IN : string

'A'

null

'B'

'C'

'C'

'D'

'C'

'E'

'D'

'F'

'D'

'G'

'E'

'G'

'E'

'H'

'F'

'G'

Result

Column1 : int

Column2 : string

0

'C, D, F'

1

'C, D, F, G'

2

'C, D, G'

3

'C, E, G'

4

'C, E, H'

[4]

Implicit start and end objects without INCOMING and OUTGOING links can also be specified explicitly via the LINK_OBJECTS operator. In the following example, A is disqualified as a START object since it is an isolated object without any outgoing links.

Query

Column1

         VARIANT ( LINK_PATH ( "Case"."ID" , CONSTRAINED BY ( START ( LINK_OBJECTS("Case"."ID")."INCOMING" = 0 AND LINK_OBJECTS("Case"."ID")."OUTGOING" > 0 ) ) ) )
        

Input

Output

Case

ID : string

NODE_ATTR : int

'A'

0

'B'

1

'C'

2

'D'

3

'E'

3

'F'

4

'G'

4

'H'

4

'J'

null

MAPPING

OUT : string

IN : string

'A'

null

'B'

'C'

'C'

'D'

'C'

'E'

'D'

'F'

'D'

'G'

'E'

'G'

'E'

'H'

'F'

'G'

Result

Column1 : string

'B, C, D, F, G'

'B, C, D, G'

'B, C, E, G'

'B, C, E, H'

[5]

The result of LINK_PATH are individual paths. However, sometimes we want to get a combined view of paths that have certain properties in common. The following example shows how to distinctively sum up the object attributes for all paths that have the same end object.

Query

Column1

         PU_LAST ( CASE_TABLE ( LINK_PATH ( "Case"."ID" ) ) , LINK_PATH ( "Case"."ID" ) )
        

Column2

         SUM ( CASE WHEN INDEX_ORDER ( UNIQUE_ID ( LINK_PATH ( "Case"."ID" ) , PU_LAST ( CASE_TABLE ( LINK_PATH ( "Case"."ID" ) ) , LINK_PATH ( "Case"."ID" ) ) ) , PARTITION BY ( UNIQUE_ID ( LINK_PATH ( "Case"."ID" ) , PU_LAST ( CASE_TABLE ( LINK_PATH ( "Case"."ID" ) ) , LINK_PATH ( "Case"."ID" ) ) ) ) ) = 1 THEN LINK_PATH ( "Case"."NODE_ATTR" ) ELSE NULL END )
        

Input

Output

Case

ID : string

NODE_ATTR : int

'A'

0

'B'

1

'C'

2

'D'

3

'E'

3

'F'

4

'G'

4

'H'

4

'J'

null

MAPPING

OUT : string

IN : string

'A'

null

'B'

'C'

'C'

'D'

'C'

'E'

'D'

'F'

'D'

'G'

'E'

'G'

'E'

'H'

'F'

'G'

Result

Column1 : string

Column2 : int

'A'

0

'G'

17

'H'

10

[6]

LINK_PATH can also handle more complex graphs that contain cycles and multiple links between two objects.

Object_Link_Cyclic_Multi_Edge_Scenario.png

LINK_PATH can also handle more complex graphs that contain cycles and multiple links between two objects.

  1. Since the output of LINK_PATH is object-based, there is no clear distinction between two possible subpaths A ➔ B over link 1 or link 2. This prevents identical paths from being duplicated, which drastically reduces the operator's output. Traversed links and their attributes can still be accessed using the LINK_PATH_SOURCE and LINK_PATH_TARGET operators.

  2. Although the output is link-independent, LINK_PATH marks the links as they are traversed so that they are not used a second time. For the given example, this means that object B can only be visited once from object C, breaking the B ➔ C ➔ B ➔ C ➔ B ➔ ... loop.

Query

Column1

         CASE_ID_COLUMN ( LINK_PATH ( "Case"."ID" , CONSTRAINED BY ( START ( "Case"."ID" = 'A' ) ) ) )
        

Column2

         LINK_PATH ( "Case"."ID" , CONSTRAINED BY ( START ( "Case"."ID" = 'A' ) ) )
        

Input

Output

Case

ID : string

NODE_ATTR : int

'A'

0

'B'

1

'C'

2

'D'

3

'E'

1

'F'

1

MAPPING

OUT : string

IN : string

EDGE_ATTR : int

'A'

'B'

1

'A'

'B'

2

'B'

'C'

3

'B'

'C'

4

'B'

'C'

6

'B'

'E'

7

'C'

'B'

5

'C'

'D'

8

'F'

'B'

9

Result

Column1 : int

Column2 : string

0

'A'

0

'B'

0

'C'

0

'B'

0

'C'

0

'D'

1

'A'

1

'B'

1

'C'

1

'B'

1

'E'

2

'A'

2

'B'

2

'C'

2

'D'

3

'A'

3

'B'

3

'E'

[7]

To limit the length of the paths, we can use the LENGTH constraint. In this example, we only want paths whose length (as measured by the number of objects) is less than or equal to 4, and the paths must start with object B.

Query

Column1

         LINK_PATH ( "Case"."ID" , CONSTRAINED BY ( LENGTH ( <= 4 ) , START ( "CASE"."ID" = 'B' ) ) )
        

Input

Output

Case

ID : string

NODE_ATTR : int

'A'

0

'B'

1

'C'

2

'D'

3

'E'

3

'F'

4

'G'

4

'H'

4

'J'

null

MAPPING

OUT : string

IN : string

'A'

null

'B'

'C'

'C'

'D'

'C'

'E'

'D'

'F'

'D'

'G'

'E'

'G'

'E'

'H'

'F'

'G'

Result

Column1 : string

'B'

'C'

'D'

'G'

'B'

'C'

'E'

'G'

'B'

'C'

'E'

'H'

See also: