1

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?

4

1 回答 1

2

您可以执行以下操作。这个想法是遍历但仅在当前节点的属性与值序列匹配时才继续向下扩展路径。我没有测试下面的代码,所以假设有错别字和缺失;

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()
        }

路径扩展器看起来像:

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)));
}
}
于 2014-01-17T21:56:48.623 回答