Search code examples
javaneo4jgraph-databasespath-findingneo4j-java-api

In Neo4j, is there any way to restrict nodes and relation types in path while using Java API?


I have source node and destination node I want to put restriction on nodes and relation types in the path. I am using Neo4j Java API.

Consider following toy example,

We have three person nodes A, B & C.

Source Node: A & Destination Node: B. There are many other kind of paths may exists between them. I want to restrict paths to specific format like-

(person) -[worksAt]-> (company) -[CompetitorOf]-> (company) <-[worksAt]- (person)

This can be very easily achieved from cypher query, but I want to know is there any way we can do it using Java API.

enter image description here

NOTE:

  1. Kindly do not suggest putting restriction on path length, that doesn't solve the problem. I want to restrict the node and relation types in path.
  2. Example mentioned above is toy example. Graph I am trying to work is more complex and there are many possible paths not feasible to traverse and validate individual paths.

Solution

  • After reading the Neo4j java documentation carefully and experimenting with the code I got following solution working-

    To filter path explored by PathFinder create a custom PathExpander using PathExpanderBuilder.

    PathExpanderBuilder pathExpanderBuilder = PathExpanderBuilder.empty();
    
    pathExpanderBuilder.add(RelationshipType.withName("worksat"), Direction.OUTGOING);
    pathExpanderBuilder.add(RelationshipType.withName("competitorof"), Direction.BOTH);
    pathExpanderBuilder.add(RelationshipType.withName("worksat"), Direction.INCOMING);
    
    PathExpander<Object> pathExpander pathExpander = pathExpanderBuilder.build();
    

    Once you create a custom PathExpander you can use it to create appropriate PathFinder which will filter traversal by the PathFinder.

    PathFinder<Path> allPathFinder = GraphAlgoFactory.allSimplePaths(this.pathExpander, 4);
    
    
    Iterable<Path> allPaths = allPathFinder.findAllPaths(sourceNode, targetNode);
    

    In our example sourceNode would be Node 'A' and targetNode would be Node 'B'.