Java – directional path in neo4j

I am faced with a seemingly simple problem I want to use the Java API to traverse the nodes of the neo4j graph However, I want to include only paths where all relationships have the same direction If what I do

db.traversalDescription().relationships(<type>,Direction.BOTH)

Path like

[a]-[:TYPE]->[b]<-[:TYPE]-[c]

That's included. I don't want it I just want the path

[a]-[:TYPE]->[b]-[:TYPE]->[c]
[a]<-[:TYPE]-[b]<-[:TYPE]-[c]

Can I help you? It seems that the solution should be very simple

Solution

The idea of Wes is introduced in detail In the custom path evaluator, you need to set the branch state to remember the direction of the first relationship All subsequent visits will check whether the last relationship matches the direction In pseudocode:

class SameDirectionPathEvaluator implements PathEvaluator<Direction> {

   public Evaluation evaluate(Path path,BranchState<Direction> state) {
      if (path.length()==0) {
         return Evaluation.EXCLUDE_AND_CONTINUE;
      } else if (path.length()==1) {
         state.setState(getDirectionOfLastRelationship(path));
         return Evaluation.INCLUDE_AND_CONTINUE;
      } else {
         if (state.getState().equals(getDirectionOfLastRelationship(path)) {
            return Evaluation.INCLUDE_AND_CONTINUE;
         } else {
            return Evaluation.EXCLUDE_AND_PRUNE;
         }
      }
   }

   private Direction getDirectionOfLastRelationship(Path path) {
      assert path.length() > 0;
      Direction direction = Direction.INCOMING
      if (path.endNode().equals(path.lastRelationship().getEndNode()) {
        direction = Direction.OUTGOING;
      }
      return direction;
   }

}

Please note that I did not compile or test the above code - it was just to draft the idea

UPDATE

There seems to be a more effective way to do this Since traversal uses the extender before calling the evaluator, it makes more sense to implement this behavior in the extender:

class ConstantDirectionExpander implements PathExpander<STATE>() {
        @Override
        public Iterable<Relationship> expand(Path path,BranchState<STATE> state) {
            if (path.length()==0) {
                return path.endNode().getRelationships(types);
            } else {
                Direction direction = getDirectionOfLastRelationship(path);
                return path.endNode().getRelationships(direction,types);
            }
        }

        @Override
        public PathExpander<STATE> reverse() {
            return this;
        }

        private Direction getDirectionOfLastRelationship(Path path) {
            assert path.length() > 0;
            Direction direction = Direction.INCOMING;
            if (path.endNode().equals(path.lastRelationship().getEndNode())) {
                direction = Direction.OUTGOING;
            }
            return direction;
        }
    }

During traversal, you need to use initialbranchsate:

TraversersDescription td = graphDatabaseService.traversalDescriptioin().
  .expand(new ConstantDirectionExpander(reltype))
  .traverse(startNode)
The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>