Find path for N levels with repeating directional relationship structure in Neo4J

I am trying to use Neo4j to analyze relationships in a family tree. I modeled it like this:

(p1:Person)-[:CHILD]->(f:Family)<-[:FATHER|MOTHER]-(p2)

I know I could have left the family label and just had children associated with each parent, but this is not practical for my purposes. Here's an example of my graph and black line is the path I want to create:

Full tree

I can request it with

MATCH p=(n {personID:3})-[:CHILD]->()<-[:FATHER|MOTHER]-()-[:CHILD]->()<-[:FATHER|MOTHER]-()-[:CHILD]->()<-[:FATHER|MOTHER]-() RETURN p

but there is a recurring pattern of relationships. Can I do something like:

MATCH p=(n {personID:3})(-[:CHILD]->()<-[:FATHER|MOTHER]-())* RETURN p

where * means repeat: CHILD, then: relationship FATHER | MOTHER, with different directions? Obviously, if the relationship were in the same direction, I could use

-[:CHILD|FATHER|MOTHER*]->

I want to be able to query Person # 3 for it up to the top of the graph, like in a pedigree, but also specify how many levels if needed (e.g. 3 generations as opposed to the end of the -line).

Another issue I ran into is if I don't overlay directions on the type relationship -[:CHILD|FATHER|MOTHER*]-

then it will start at Person # 3 and go in the direction I want (alternating arrows) but also go down the chain finding all the others "cousins, aunts, uncles, etc.".

Any seasoned Cypher experts who help me?

+3


source to share


3 answers


You can change the focus of the relationship CHILD

in your model, as in:

(p1:Person)<-[:CHILD]-(f:Family)<-[:FATHER|MOTHER]-(p2)

      



This way you can use a simple pattern -[:CHILD|FATHER|MOTHER*]->

in your queries.

Direction reversal is also intuitive, as you can more naturally visualize the graph as a family tree, with all arrows flowing downward from ancestor to descendant.

+1


source


Yes, this is an interesting case. I am sure (although I am open to a fix) that this is simply not possible. Can you have and support both? You can have a simple cypher request to create additional relationships:



MATCH (parent)-[:MOTHER|FATHER]->()<-[:CHILD]-(child)
CREATE (child)-[:CHILD_OF]->parent

      

0


source


So here's a thought:

MATCH path=(child:Person {personID: 3})-[:CHILD|FATHER|MOTHER*]-(ancestor:Person),
WHERE ancestor-[:MOTHER|FATHER]->()
RETURN path

      

Usually I would use the second sentence in the MATCH

following way:

MATCH
  path=(child:Person {personID: 3})-[:CHILD|FATHER|MOTHER*]-(ancestor:Person),
  ancestor-[:MOTHER|FATHER]->()
RETURN path

      

But Neo4j (at least by default, I guess) doesn't follow the path. Maybe comma separation would be fine and that would be a problem:

MATCH path=(child:Person {personID: 3})-[:CHILD|FATHER|MOTHER]-(ancestor:Person)-[:MOTHER|FATHER]->()

      

I'm curious to see what you find!

0


source







All Articles