1

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.
c0der
  • 18,467
  • 6
  • 33
  • 65
Anwar Shaikh
  • 1,591
  • 3
  • 22
  • 43

2 Answers2

3

It's not really clear from your question what you're actually trying to compute. Do you have A and B and want to find if their companies are competitors? Do you have C and want to find who among their friends work at competing companies?

Anyway, if you're using the traversal API (you're talking about paths), you can write a custom PathExpander which will use the last relationship in the Path to determine the next type of relationship to traverse.

If you're just traversing the relationships manually, I don't really see the problem: just call Node.getRelationships(RelationshipType, Direction) with the proper parameters at each step.

Contrary to what you do in Cypher, you don't declare the pattern you're looking for in the path, you just compute the path to follow the wanted pattern.

Frank Pavageau
  • 11,477
  • 1
  • 43
  • 53
0

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'.

Anwar Shaikh
  • 1,591
  • 3
  • 22
  • 43