cancel
Showing results for 
Search instead for 
Did you mean: 

Head's Up! These forums are read-only. All users and content have migrated. Please join us at community.neo4j.com.

Compute total share for all nodes in tree

I have the following data structure:

(A:Company)-[OWNS]->(B:Company)-[OWNS]->(D:Company)
(A:Company)-[OWNS]->(C:Company)-[OWNS]->(D:Company)

Each [OWNS] relation has a property: share. So for example, A owns 100% of B and 100% of C, and B owns 45% of D and C owns 5% of D. I want to compute the total share that A owns of D. I can do that using the following:

MATCH (n:Company) where n.company_id IN [companyA_id, companyD_id]
    WITH collect(n) as nodes
    UNWIND nodes as n
    UNWIND nodes as m
    WITH * WHERE id(n) < id(m)
    MATCH path = allShortestPaths( (n)-[*..10]-(m) )
    return REDUCE(total_share = 0.0, share in collect(REDUCE(share = 1.0, owner IN relationships(path) | share*owner
.andel)) | total_share + share) as total_share

So far, so good. But what if I want to return all nodes in the tree that has A at the head of the branch, with the total share owned for each node in the tree? I can't quite wrap my head around how to do that. And what if I want to return all the nodes in the tree that has a total share of more than 50% (with their share)? So I want to return all the b's with their total shares in this tree:

MATCH tree = (a:Company)-[owners:OWNS*0..10]->(b:Company) return tree

I can do it by using another language to call neo4j repeatedly, but it would be great if cypher could do it on it's on.

2 REPLIES 2

ameyasoft
Graph Maven
You can use apoc.path.spanningTree:

MATCH (n:Company)
WHERE n.id = 100
CALL apoc.path.spanningTree(a, {}) YIELD path
return path

But then, how do I go from that path to computing all the shares? I would have to loop through all the nodes in the path and then follow all paths to the parent to get the correct share. Does the spanning tree include all shortest paths among nodes in the tree?