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.

Lowest common ancestor with algo.shortestPath.stream and cypher projection

neo4j-desktop: 1.2.2 ce
neo4j-browser: 3.2.24 (p2neo v.4)
APOC: 3.5.0.5
Graph-Algo: 3.5.11.0
GraphQL: 3.5.0.4
Graph size: 159 760 nodes, 389 554 relations

Hi,
I want to find the lowest common ancestor (lca) of two words, because I want to compare the similarity of my profession based on their semantic relations.

I have a Graph like this:

CREATE (profession_1:Profession {title: 'Goldsmith'})
CREATE (profession_2:Profession {title: 'Silversmith'})
CREATE (profession_3:Profession {title: 'Blacksmith'})
CREATE (profession_4:Profession {title: 'Carpenter'})

CREATE (task_1:pa {id:'1', description: 'forge gold to necklace and ring'})
CREATE (task_2:pa {id:'2', description: 'mould silver to ring and finger ring'})
CREATE (task_3:pa {id:'3', description: 'forge iron to chain'})
CREATE (task_4:pa {id:'4', description: 'saw wood to board'})
CREATE (task_5:pa {id:'5', description: 'check gold'})
CREATE (task_6:pa {id:'6', description: 'check silver'})
CREATE (task_7:pa {id:'7', description: 'make furniture from wood'})

CREATE (GNROOT:Lexunit {lexunit_id: '1', orth_form: 'GNROOT', depth: 0})
CREATE (forge:Lexunit {lexunit_id: '2', orth_form: 'forge', depth: 3})
CREATE (mould:Lexunit {lexunit_id: '3', orth_form: 'mould', depth: 3})
CREATE (saw:Lexunit {lexunit_id: '4', orth_form: 'saw', depth: 3})
CREATE (gold:Lexunit {lexunit_id: '5', orth_form: 'gold', depth: 4})
CREATE (silver:Lexunit {lexunit_id: '6', orth_form: 'silver', depth: 4})
CREATE (iron:Lexunit {lexunit_id: '7', orth_form: 'iron', depth: 4})
CREATE (wood:Lexunit {lexunit_id: '8', orth_form: 'wood', depth: 2})
CREATE (necklace:Lexunit {lexunit_id: '9', orth_form: 'necklace', depth: 2})
CREATE (ring:Lexunit {lexunit_id: '10', orth_form: 'ring', depth: 2})
CREATE (chain:Lexunit {lexunit_id: '11', orth_form: 'chain', depth: 2})
CREATE (board:Lexunit {lexunit_id: '12', orth_form: 'board', depth: 2})
CREATE (cast:Lexunit {lexunit_id: '13', orth_form: 'cast', depth: 2})
CREATE (cut:Lexunit {lexunit_id: '14', orth_form: 'cut', depth: 2})
CREATE (make:Lexunit {lexunit_id: '15', orth_form: 'make', depth: 1})
CREATE (precious_metal:Lexunit {lexunit_id: '16', orth_form: 'precious metal', depth: 3})
CREATE (heavy_metal:Lexunit {lexunit_id: '17', orth_form: 'heavy metal', depth: 3})
CREATE (metal:Lexunit {lexunit_id: '18', orth_form: 'metal', depth: 2})
CREATE (ressource:Lexunit {lexunit_id: '19', orth_form: 'ressource', depth: 1})
CREATE (jewellery:Lexunit {lexunit_id: '20', orth_form: 'jewellery', depth: 1})
CREATE (string:Lexunit {lexunit_id: '21', orth_form: 'string', depth: 1})
CREATE (part_of_building:Lexunit {lexunit_id: '22', orth_form: 'part of building', depth: 1})
CREATE (finger_ring:Lexunit {lexunit_id: '23', orth_form: 'finger ring', depth: 3})
CREATE (check:Lexunit {lexunit_id: '24', orth_form: 'check', depth: 1})
CREATE (furniture:Lexunit {lexunit_id: '25', orth_form: 'furniture', depth: 1})

MERGE (profession_1)-[:HAS_PA]->(task_1)
MERGE (profession_2)-[:HAS_PA]->(task_2)
MERGE (profession_3)-[:HAS_PA]->(task_3)
MERGE (profession_4)-[:HAS_PA]->(task_4)
MERGE (profession_1)-[:HAS_PA]->(task_5)
MERGE (profession_2)-[:HAS_PA]->(task_6)
MERGE (profession_4)-[:HAS_PA]->(task_7)

MERGE (task_1)-[:HAS_ARB]->(forge)
MERGE (task_1)-[:HAS_MAT]->(gold)
MERGE (task_1)-[:HAS_PRO]->(necklace)
MERGE (task_1)-[:HAS_PRO]->(ring)

MERGE (task_2)-[:HAS_ARB]->(mould)
MERGE (task_2)-[:HAS_MAT]->(silver)
MERGE (task_2)-[:HAS_PRO]->(ring)
MERGE (task_2)-[:HAS_PRO]->(finger_ring)

MERGE (task_3)-[:HAS_ARB]->(forge)
MERGE (task_3)-[:HAS_MAT]->(iron)
MERGE (task_3)-[:HAS_PRO]->(chain)

MERGE (task_4)-[:HAS_ARB]->(saw)
MERGE (task_4)-[:HAS_MAT]->(wood)
MERGE (task_4)-[:HAS_PRO]->(board)

MERGE (task_5)-[:HAS_ARB]->(check)
MERGE (task_5)-[:HAS_MAT]->(gold)

MERGE (task_6)-[:HAS_ARB]->(check)
MERGE (task_6)-[:HAS_MAT]->(silver)

MERGE (task_7)-[:HAS_ARB]->(make)
MERGE (task_7)-[:HAS_MAT]->(wood)
MERGE (task_7)-[:HAS_PRO]->(furniture)

MERGE (forge)-[:HAS_HYPERNYM]->(cast)
MERGE (mould)-[:HAS_HYPERNYM]->(cast)
MERGE (saw)-[:HAS_HYPERNYM]->(cut)
MERGE (cast)-[:HAS_HYPERNYM]->(make)
MERGE (cut)-[:HAS_HYPERNYM]->(make)
MERGE (make)-[:HAS_HYPERNYM]->(GNROOT)
MERGE (gold)-[:HAS_HYPERNYM]->(precious_metal)
MERGE (silver)-[:HAS_HYPERNYM]->(precious_metal)
MERGE (iron)-[:HAS_HYPERNYM]->(heavy_metal)
MERGE (precious_metal)-[:HAS_HYPERNYM]->(metal)
MERGE (heavy_metal)-[:HAS_HYPERNYM]->(metal)
MERGE (metal)-[:HAS_HYPERNYM]->(ressource)
MERGE (wood)-[:HAS_HYPERNYM]->(ressource)
MERGE (necklace)-[:HAS_HYPERNYM]->(jewellery)
MERGE (ring)-[:HAS_HYPERNYM]->(jewellery)
MERGE (finger_ring)-[:HAS_HYPERNYM]->(ring)
MERGE (chain)-[:HAS_HYPERNYM]->(string)
MERGE (board)-[:HAS_HYPERNYM]->(part_of_building)
MERGE (jewellery)-[:HAS_HYPERNYM]->(GNROOT)
MERGE (string)-[:HAS_HYPERNYM]->(GNROOT)
MERGE (part_of_building)-[:HAS_HYPERNYM]->(GNROOT)
MERGE (ressource)-[:HAS_HYPERNYM]->(GNROOT)
MERGE (check)-[:HAS_HYPERNYM]->(GNROOT)
MERGE (furniture)-[:HAS_HYPERNYM]->(GNROOT)

simple matches like:
MATCH p = (n:Lexunit {orth_form: "mould"})-[:HAS_HYPERNYM*]->(x)<-[:HAS_HYPERNYM*]-(m:Lexunit {orth_form: "saw"}) RETURN x.depth
have to bad performance for my real graph, but algorythms like:

MATCH aspaths = AllShortestPaths( (start:Lexunit{orth_form:'mould'})-[*]-(end:Lexunit{orth_form:'saw'}) )
WHERE ALL (r in relationships(aspaths) WHERE type(r) = 'HAS_HYPERNYM')
RETURN aspaths

have the possibility, that they don't find the lowest common ancestor, but only a common relative, because the relation have to be directed to the ancestor
(start)-[rel]->(lca)<-[rel]-(end)
If it's not
(start)-[rel]-(lca)-[rel]-(end)
it takes sometimes a path, where it goes the tree up again. So I tried to use a more complex query:

MATCH (start:Lexunit{orth_form:'mould'}), (end:Lexunit{orth_form:'saw'})
CALL algo.shortestPath.stream(start, end, 'distance', {
nodeQuery:'MATCH(n:Lexunit) RETURN id(n) as id',
relationshipQuery:'MATCH(n:Lexunit)-[:HAS_HYPERNYM*]->(x)<-[:HAS_HYPERNYM*]-(m:Lexunit) RETURN id(n) as source, id(m) as target, count(*) as weight',
graph:'cypher'})
YIELD nodeId, cost
RETURN algo.asNode(nodeId).orth_form AS name, cost

...but it only shows me the start an end path:
╒═══════╤══════╕
│"name" │"cost"│
╞═══════╪══════╡
│"mould"│0.0 │
├───────┼──────┤
│"saw" │1.0 │
└───────┴──────┘

I'd be very grateful for a little help here.

Profile from the last query:

Thanks!

0 REPLIES 0