简体   繁体   中英

Neo4j: hierarchy finding cypher query

I am trying to find the hierarchy - both upward and downward for the following domain model. As being new to neo4j I am having some hurdle to get the right hierarchy with the cypher query.

Any assistance or sample would be a great help to me...

(:Person{id=1})-[HAS_CHILD]->(:Person{id=2})-[HAS_CHILD]->(:Person{id=3})-[HAS_CHILD]->(:Person{id=4})-[HAS_CHILD]->(:Person{id=5})

....like that to a very deep level & one person can have multiple children.

I am trying to build some query to find

  1. A Person and all his children hierarchy

  2. A person and his parent hierarchy

  3. Relation ship between two person - if any

  4. A Person and all his children hierarchy - up to a specific depth

These should work.

The WHERE clauses are for eliminating subpaths. The answer for #4 cannot use the same WHERE clause, so the results will contain subpaths.

1.

MATCH p=(:Person{id:1})-[:HAS_CHILD*]->(c)
WHERE NOT (c)-[:HAS_CHILD]->()
RETURN NODES(p);

2.

MATCH p=(:Person { id:5 })<-[:HAS_CHILD*]-(ancestor)
WHERE NOT (ancestor)<-[:HAS_CHILD]-()
RETURN NODES(p);

3.

MATCH p=(p5:Person { id:5 })-[:HAS_CHILD*]-(p1:Person { id:1 })
RETURN NODES(p);

4. Using a depth up to 5:

MATCH p=(:Person{id:1})-[:HAS_CHILD*1..5]->(c)
RETURN NODES(p);

Using your datamodel consisting of (:Person)-[:HAS_CHILD]->(:Person) these queries should return the data you are looking for (let's also assume you have a unique name property on each Person node to facilitate a lookup by name, but you could also use any unique id/property):

A person and all his children

We can use a variable length path pattern here to match on patterns containing multiple HAS_CHILD relationships.

MATCH (p:Person)-[:HAS_CHILD*]->(child:Person)
WHERE p.name = "Bob Loblaw"
RETURN child;

A person and his parent hierarchy

Very similar to the above query, but we just reverse the relationship direction.

MATCH (p:Person)<-[:HAS_CHILD*]-(ancestor:Person)
WHERE p.name = "Bob Loblaw"
RETURN ancestor;

Relationship between two person - if any

We can use the shortestPath function to find the shortest path between two nodes in the graph. This query will return no rows if no path is found.

MATCH path=shortestPath((p:Person {name: "Bob Loblaw"})-[*]-(o:Person {name: "Louise Bluth"}))
RETURN path

A person and their child hierarchy - up to a specific depth

This query is very similar to the previous "person and all his children query" however we can specify bounds on the variable length path. Note : an upper bound should always be specified with variable length paths to avoid very long running queries.

MATCH (p:Person)-[:HAS_CHILD*1..5]->(child:Person)
WHERE p.name = "Bob Loblaw"
RETURN child;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM