cancel
Showing results for 
Search instead for 
Did you mean: 

Head's Up! These forums are read-only. All users and content have migrated. Please join us at community.neo4j.com.

Inferencing/Reasoning in Neo4j using Ontology

Hi

I want to do inferencing/reasoning in Neo4j using the data stored in neo4j and a related ontology(created in Neo4j).
I created an Ontology saying X-has_mother->Y and Y-has_mother->Z , then X-has_grandmother->Z.
Also, I have created a number of Person nodes in neo4j which have relations has_mother,
now using the ontology created I want to find all the grandmother relations in the data.
I have explored the neosemantics' Inference/Reasoning part , but could not get the appropriate function to do so.
Can yo please suggest how this kind of inferencing be done in Neo4j.

3 REPLIES 3

Can't you figure out each grandchild and associated grandmother with the following query:

match(grandchild:Person)-[:HAS_MOTHER*2..2]->(grandmother:Person)
return grandchild, grandmother

The query finds two people that are related with exactly two directed HAS_MOTHER relationships between them.

BTW- the syntax allows for the above to also be simplified to the below statement, but the '*2..2' is more illustrative.

match(grandchild:Person)-[:HAS_MOTHER*2]->(grandmother:Person)
return grandchild, grandmother

Hi

Yes, this is possible if we have the same type of relations. But in case we have something like
X-has_mother->Y and Y-has_husband->Z, then X-has_father->Z.
How to extract these type of indirect/inferred relation using the Ontology and Neo4j.

Each definition of a relationship between person X and person Z in your ontology, can be represented by a cypher pattern. In your example, the following query would determine this person's father if it exists:

match(person:{name;$name})-[:HAS_MOTHER]->()-[:HAS_HUSBAND]->(father)
return person, father

I guess you would define a cypher pattern that represents each relationship between person X and Z defined in your ontology, then test for the existence of each for a given person X. This would give you all the relationships for person X. Or, given a person X, person Z, and relationship R, you could determine if X and Z are related by relationship R, by determining if the cypher pattern exists between the entity X and entity Z.

This seems to be a more powerful solution than using a rules engine, such as Drools to do the same. In that case you would create rules, as "if X has mother Y and Y has husband Z, then X has father Z". You would then provide data, such as X has mother Y and Y has husband Z as facts. Drools would create an execution tree that looks for matching patterns based on the collection of your rules. In this case if your facts given to the rules engine upon execution contained the two relationships you defined in this one rule relating a person to its father through mother/husband relationships, the specific rule would get triggered and provide the result that Z is the father of X. In contrast, with cypher you can just define a cypher pattern that defines this relationship directly and the query will find the relationships or can be used to validate the relationship between two entities. You have to explicitly test for each type of relationship in your ontology, but this is what Drools does, as its execution tree will include every relationship you have defined in your set of rules that make up the knowledge base. A huge difference is that you have to define all your rules upfront in Drools and compile to a knowledge base, which you can then use to evaluate a given set of facts. This has to be done within an application. The cypher solution allows you do run ad hoc queries for any relationships you define, either in Desktop or using one of the language drivers if you want to wrap the functionality in an application.