2014-01-17 39 views
1

第一個如下所示:給定一個指定路徑的屬性序列,我應該返回末端節點。即需要幫助將這兩個Cypher查詢翻譯爲遍歷框架

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

,第二個是種相反:給定的節點的標識符(爲簡單起見假設它是該節點的ID),該路徑從根(屬性name的序列)返回到節點(它保證獨一無二)。至於現在,我只是用了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 

查詢是從嵌入式數據庫上運行,而不是用他們的速度滿足我,所以我想他們已經翻譯成TraversalDescription S,但他們應該動態改變,我不太明白如何做到這一點。

或者這些查詢可能不是最優?具有shortestPath的那個運行< = 1ms,而具有可變長度的那個運行每個查詢10ms(這是不可接受的)。也許你對我有一些性能提示?

回答

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))); 
} 
} 
+0

非常感謝,馬克斯,真正幫助。這些變化甚至比我預想的還要重要。所以,這裏是我現在使用的一段代碼:http://paste.ubuntu.com/6796366/。我的觀察結果是:1)廣度優先搜索的運行時間是深度搜索的兩倍; 2)不是返回不存在的關係,最好返回一個空的列表,這是JVM上的單例,因此不會導致創建新對象,這在長路徑上會很痛苦; 3)這個擴展器用法的例子非常棒 - 它們應該已經在文檔中使用了!非常感謝您的幫助。 – tkroman

+0

啊,關於速度。之前:每秒穿越100次,之後:每秒穿越8000次。 – tkroman