Question

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?

Was it helpful?

Solution

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)));
}
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top