Reputation: 36349
I'm modeling a set of nodes which has some hierarchical relationships (as a PARENT relationship) but additionally some non-hierarchical relationship.
Let's say it's a family tree with relationships to the birth country for each person, for simplicity
So each birth country is a node and each person is a node, and I might create the relationship in cypher as:
start parent=node(123), child=node(456)
create parent-[:PARENT]->child;
and
start person=node(123), country=node(789)
create person-[:BORN_IN]->country;
what I'd like to do is, for example, get a list of folks who don't have any ancestors from England, or folks who do have an ancestor from Japan, or the like. I feel like this should be a reasonable query, but I am new to cypher and haven't a clue how to construct it.
UPDATE ** After more extensive testing of cases, I've found that the query doesn't work exactly right in some. Given a child with one parent from England and a grandparent not from England, a query for children without any ancestors from England incorrectly returns the child with a parent from England. It looks like the way I've written the query, I get a return for the grandparent having a NULL relationship to england. My query is as follows:
START n=node(*), ancestor=node(123)
MATCH n-[r:PARENT*]->o-[b?:BORN_IN]->ancestor
WHERE b IS NULL
RETURN DISTINCT n;
If all the person's ancestors were born in the country in question, it works fine.
Upvotes: 1
Views: 2094
Reputation: 19373
You can use a variable length relation to include all children/ancestors. I just picked the "folks who do have an ancestor from Japan":
START country=<lookup Japan>
match (child)-[:PARENT*0..5]->(parent)-[:BORN_IN]->(country)
return child
Note: have not tried it but logically this should do it. Also I picked a random depth of 5.
MATCH a-[:PARENT]->b-[:BORN_IN]->z
as mentioned in your example should find all persons (a) who have a parent born in z
If you have a data set handy on console.neo4j.org maybe, could take a look at what's happening.
Upvotes: 4