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:
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?
source to share
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.
source to share
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
source to share
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!
source to share