Cypher query to implement type inheritance

I have a type hierarchy presented in a Neo4j database. All types have one or more relationships :parent

that indicate other types. The root of the hierarchy is related :parent

to itself.

All other nodes in the database have one or more relationships :type

that indicate the type of node. Here is a simple example where the root of the type hierarchy is entity

:

Scheme

  • rat

    - [: parent] β†’ rodent

  • rodent

    - [: parent] β†’ animal

  • dog

    - [: parent] β†’ animal

  • animal

    - [: parent] β†’ entity

  • pet

    - [: parent] β†’ entity

  • entity

    - [: parent] β†’ entity

Now tell me I have a node representing my favorite rat, Larry. node has a relationship :type

as pet

well as to rat

:

  • Larry

    - [Type] β†’ pet

  • Larry

    - [Type] β†’ rat

However, within certain rules hierarchy Larry types include not only pet

and rat

, but also rodent

, and entity

.

Question

I want to create a query for any type so that it returns all nodes of that type according to the hierarchy. Obviously finding connected nodes does not work directly. I tried several things using relationships -[:type:parent*]->

to map arbitrary length paths to a target, but the request time was unacceptably long. What is the efficient way to implement the above?

+3


source to share


1 answer


I think you have the right idea. The performance should be decent if you write your query correctly.

A simple cypher should be able to do this:

MATCH (larry {name: "Larry"})-[:type:parent*]->(intermediateTypes)-[:parent]->(rootType { label: "ROOT" })
RETURN intermediateTypes;

      



It stops looking at the top and gets everything in the middle.

Note that this query can be quite tricky and can take a long time if you have multiple inheritance in your type tree or if it's just not a tree at all ... in this case, in a large graph, cypher can be pretty while chasing your tail around looking for a path to the root, if, for example, there were ribs saying something like (animal)-[:parent]->(rat)

. This will be the problem with your data, not the cypher. In this case, you can map shortestPath

to Larry

with the root type instead .

+1


source







All Articles