Head's Up! These forums are read-only. All users and content have migrated. Please join us at community.neo4j.com.
03-13-2020 12:25 PM
Hi, I am new to Neo4j but have handled graphs in R (igraph) for years. I would like to move some of my R logic into cypher, like the case in the picture above. In this case, which is a network of ownership of companies, that could be own by other companies but in the end there are persons that are the real owners of a given company. For the company "A" I want to nest the ownership "pct" to all persons end nodes and calculate the ownership share along the paths.
The follwing query might be a good starting point:
Match (p:Pers) -[r:OWNS*0..] -> (n:Comp {name: 'A'} )
,path = (p) - [r:OWNS*0..] -> (n:Comp {name: 'A'} )
return path
that gives me a row for each person a path to A
name pct val name1 pct1 val1 name2
<chr> <int> <int> <chr> <int> <int> <chr>
1 P4 100 150 F 10 100 A
2 P5 10 100 A NA NA NA
3 P2 30 30 D 70 100 A
4 P1 70 30 D 70 100 A
5 P3 100 10 E 10 100 A
The ownership share for for row 3 (P2) would be pct(pct1/100) ->30(70/100) = 21
So the question is how to iterate through all rows, get the pct values and perform the calculations.
I have tried with variuos approches with "WITH" AND "UNWIND" but no luck so far.
Below is a script for cerating the sample graph for reusability.
Thanks,
Roger
MERGE (a:Comp {name: 'A', val: 100})
MERGE (b:Comp {name: 'B', val: 1000})
MERGE (c:Comp {name: 'C', val: 70})
MERGE (d:Comp {name: 'D', val: 30})
MERGE (e:Comp {name: 'E', val: 10})
MERGE (f:Comp {name: 'F', val: 150})
MERGE (g:Comp {name: 'G', val: 200})
MERGE (p1:Pers {name: 'P1'})
MERGE (p2:Pers {name: 'P2'})
MERGE (p3:Pers {name: 'P3'})
MERGE (p4:Pers {name: 'P4'})
MERGE (p5:Pers {name: 'P5'})
MERGE (d)-[:OWNS {pct: 70}]-(a)
MERGE (e)-[:OWNS {pct: 10}]-(a)
MERGE (e)-[:OWNS {pct: 100}]-(b)
MERGE (f)-[:OWNS {pct: 10}]-(a)
MERGE (p5)-[:OWNS {pct: 10}]-(a)
MERGE (p5)-[:OWNS {pct: 100}]-(c)
MERGE (p1)-[:OWNS {pct: 70}]-(d)
MERGE (p2)-[:OWNS {pct: 30}]-(d)
MERGE (p3)-[:OWNS {pct: 100}]-(e)
MERGE (p4)-[:OWNS {pct: 100}]-(f)
Solved! Go to Solution.
03-13-2020 03:58 PM
Thanks for the detail and sample graph, that makes this much easier.
Since you know :Person nodes and a single :Company node are the endpoints of your pattern, you can match using a variable-length path as you used before.
You don't actually need the second part, the first line is enough (though we'll need the path variable in there).
Using the path variable, we have access to relationships(path)
, which is a list of all the relationships on the path.
We can use the reduce function to deal with an accumulation of values from the relationships of the path.
Here's the query that will work for all persons and Company A:
MATCH path = (p:Pers) -[:OWNS*0..] -> (n:Comp {name: 'A'} )
RETURN p.name as name, reduce(total=100.0, rel in relationships(path) | total * (rel.pct / 100.0)) as totalPercent
03-13-2020 03:58 PM
Thanks for the detail and sample graph, that makes this much easier.
Since you know :Person nodes and a single :Company node are the endpoints of your pattern, you can match using a variable-length path as you used before.
You don't actually need the second part, the first line is enough (though we'll need the path variable in there).
Using the path variable, we have access to relationships(path)
, which is a list of all the relationships on the path.
We can use the reduce function to deal with an accumulation of values from the relationships of the path.
Here's the query that will work for all persons and Company A:
MATCH path = (p:Pers) -[:OWNS*0..] -> (n:Comp {name: 'A'} )
RETURN p.name as name, reduce(total=100.0, rel in relationships(path) | total * (rel.pct / 100.0)) as totalPercent
03-14-2020 08:07 AM
Perfect!
Thanks for the help Andrew.
br
Roger
All the sessions of the conference are now available online