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