GQL

Aggregating Edge Weights in GQL

Often times we have to aggregate the weights along paths (edges) in a Graph. GQL provides a REDUCE function for this. We will use Ultimate Beneficial Ownership (UBO) graph to demonstrate this.

A beneficial owner is defined as a physical person “who directly or indirectly owns or controls a sufficient part of the shares or the voting rights, or who practices control through other means.”.

If a company is owned by another company (e.g. a holding company), it is the physical person(s) who ultimately own(s) the company who shall be registered as beneficial owner(s). Identifying Ultimate Beneficial Ownership (UBO) can be challenging due to complex and opaque ownership structures. But Property Graphs and GQL make this process easier.

Let’s take a look at the following Beneficial Ownership chart

Let’s create a the dataset based on the above Beneficial Ownership chart:


create graph ubo_graph {
  node person ({name string})
  , node business ({name string})
  , edge owns ()-[{percentage float}]->()
};

use ubo_graph;

insert 
  (n_uroosa:person {_id:'uroosa', name:'Uroosa'})
  , (n_fatima:person {_id:'fatima', name:'Fatima'})
  , (n_maryam:person {_id:'maryam', name:'Maryam'})
  , (n_zainab:person {_id:'zainab', name:'Zainab'})
  , (n_hannah:person {_id:'hannah', name:'Hannah'})
  , (n_acme_corp:business {_id:'acme corp', name:'Acme Corp.'})
  , (n_northwind:business {_id:'northwind', name:'Northwind'})
  , (n_fourth_cofee:business {_id:'fourth coffee', name:'Fourth Coffee'})
  , (n_tasmanian_traders:business {_id:'tasmanian traders', name:'Tasmanian Traders'})
  , (n_coffee_corp:business {_id:'coffee corp', name:'Coffe Corp.'})
  , (n_blue_yonder:business {_id:'blue yonder', name:'Blue Yonder'})
  , (n_hotel_kitchen_sink:business {_id:'hotel kitchen sink', name:'Hotel Kitchen Sink'})
  , (n_uroosa)-[e1:owns {percentage:0.80}]->(n_acme_corp)
  , (n_uroosa)-[e2:owns {percentage:0.15}]->(n_hotel_kitchen_sink)
  , (n_fatima)-[e3:owns {percentage:0.20}]->(n_acme_corp)
  , (n_zainab)-[e4:owns {percentage:0.19}]->(n_fourth_cofee)
  , (n_maryam)-[e5:owns {percentage:1.0}]->(n_coffee_corp)
  , (n_acme_corp)-[e6:owns {percentage:0.30}]->(n_fourth_cofee)
  , (n_northwind)-[e7:owns {percentage:0.09}]->(n_hotel_kitchen_sink)
  , (n_tasmanian_traders)-[e8:owns {percentage:0.49}]->(n_blue_yonder)
  , (n_coffee_corp)-[e9:owns {percentage:0.51}]->(n_blue_yonder)
  , (n_blue_yonder)-[e10:owns {percentage:0.51}]->(n_fourth_cofee)
  , (n_fourth_cofee)-[e11:owns {percentage:0.51}]->(n_hotel_kitchen_sink)
  , (n_hannah)-[e12:owns {percentage:0.25}]->(n_hotel_kitchen_sink)
;

Now let’s see how the REDUCE function can be used to calculate the aggregate along the path. We will calculate the Uroosa’s total Ownership for the Hotel Kitchen Sink. Notice that Uroosa directly owns a share of the Hotel Kitchen Sink and also through a separate business entities (Acme Corp. and Fourth Coffee). We will need to account for both of these paths:

We can use the following GQL to Calculated the Ownership Percentage along each Path:

match path = all (a:person {_id:'uroosa'})
  -[owns]
  ->{0,} (b:business {_id:'hotel kitchen sink'})
return path, 
  reduce(total_ownership = 1 , own in owns | total_ownership * own.percentage);

Notice the use of the REDUCE function to calculate the total_ownership. This will output:

This corresponds to 0.8 x 0.3 x 0.51 = 0.1224 through Acme Corp. and Fourth Coffee and direct share of 0.15 in Hotel Kitchen Sink.

We can also use the Linear Composition in GQL to sum up the Ownership percentages (0.15 + 0.1224) as following

match path = all (a:person {_id:'uroosa'})-[owns]->{0,} (b:business {_id:'hotel kitchen sink'})
return path, 
reduce(total_ownership = 1 , own in owns | total_ownership * own.percentage) as ownership
next 
return sum(ownership)
;

Notice the use of NEXT to formulate the Linear Statement Composition. This will output:

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *