Ryan Kauk
Ryan Kauk

Reputation: 63

Neo4j get middle node in path

I'm using neo4j with wordnet to be able to calculate the similarity between words. However I'm not too good with cypher yet.

What I want is to be able to get the path between two nodes in a hierarchal pattern, but I need to know the ancestor in the middle of them. So if you consider this graph and assume each block is a word and we have the c node and b node already and want to get the path and for it to be able to return the ancestor node, a.

The query i was trying with was MATCH (synset:wdo#Synset {id:"wn/100015568-n"}), (synset1:wdo#Synset {id:"wn/113957498-n"}), path = shortestPath((synset)-[:wdo#hyponym|wdo#hypernym*]-(synset1)) return path

which got me the path but I can't get the shared ancestor from it. Any help would be appreciated thank you.

Upvotes: 0

Views: 435

Answers (2)

Antimony
Antimony

Reputation: 2240

You probably want something that recursively goes down relationships, like in this StackOverflow answer.

In your case, to get the common ancestor, you could try

MATCH (child1:node) <- [:RELATIONSHIP*1..] - (ancestor:node) - [:RELATIONSHIP*1..] -> (child2:node)
WHERE child1.id = c
AND ancestor.id = a
AND child2.id = b
RETURN a

The code is untested, and you'll need to fill in the right kind of node labels and relationships for your case.

Upvotes: 1

Gabor Szarnyas
Gabor Szarnyas

Reputation: 5047

You could take all consequent (x, y, z) node triples in the path and check if y is an ancestor of x and z:

MATCH ...
WITH nodes(path) AS np
UNWIND range(1, length(np)) AS i
WITH np[i-1] AS x, np[i] AS y, np[i+1] AS z
WHERE ((x)-[:hypernym]->(y) OR (x)<-[:hyponym]->(y))
  AND ((z)-[:hypernym]->(y) OR (z)<-[:hyponym]->(y))
RETURN y

(The query is untested and may require some tuning. Also, please check my comments on data modeling.)

Upvotes: 0

Related Questions