문제

The first one is as follows: given a sequence of properties that specify a path, I should return the the end node. i.e.

start r=node(0)
match r<-[:R]-({n:"aaa"})<-[:R]-({n:"bbb"})<-[:R]-(x {n:"ccc"})
    return x as node

And the second one is kind of opposite: given a node's identifier (for simplicity suppose it is the node's ID), return the path (sequence of properties name) from the root to the node (it's guaranteed to be unique). As for now, I'm just using the shortestPath:

start n=node(1000), root = node(0) 
match p = shortestPath(root<-[:R*]-n) 
return
    reduce(fullpath = '', pt IN nodes(p) | fullpath + pt.n)
    as path

The queries are run from embedded database and aren't satisfying me with their speed, so I'd like to have them translated into TraversalDescriptions, but they should change dynamically, and I don't quite understand how to do this.

Or maybe these queries aren't optimal? The one with the shortestPath runs for <= 1ms, while the one with variable length runs for 10ms per single query (that's unacceptable). Maybe you have some performance tips for me?

도움이 되었습니까?

해결책

You can do something like the following. The idea is to traverse but only continue to expand down the path if the properties of the current node match the sequence of values. I haven't tested the code below, so assume typos and missing ;

Node r = db.getNodeById(0);
String[] sequence = {"aaa","bbb","ccc"};

Traverser traverser = Traversal.description()
                .depthFirst()
                .expand(new ArrayExpander(sequence))
                .evaluator(Evaluators.atDepth(sequence.length()))
                .uniqueness(Uniqueness.NONE)
                .traverse(r);

for ( org.neo4j.graphdb.Path p : traverser )
        {
            //do something with the nodes accessible by p.nodes()
        }

The path expander looks something like:

public class ArrayExpander implements PathExpander {

private String[] sequence;

public ArrayExpander(String[] sequence)
{
    this.sequence = sequence;
}

public Iterable<Relationship> expand(Path path, BranchState state){
    if(path.endNode().getProperty("n").equals(sequence[path.length()]){
      return path.endNode().getRelationships(Direction.INCOMING);
    } else {
      return path.endNode().getRelationships(DynamicRelationshipType.withName("IDONTEXIST"));
     }

}

public ArrayExpander reverse()
{
    return new ArrayExpander(Collections.reverse(Arrays.asList(sequence)));
}
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top