2017-02-15 135 views
0

以下基本圖:獲得的唯一路徑數量穿越而穿越利用我創建的Neo4j穿越API

CREATE (:NodeType1 {prop1:'value1'})-[:RelType1 {prop2:'value2'}]->(:NodeType2 {prop3:'value3'})-[:RelType2 {prop4:'value4'}]->(:NodeType3 {prop5:'value5'})-[:RelType3 {prop6:'value6'}]->(:NodeType4 {prop7:'value7'}) 

CREATE (:NodeType1 {prop1:'value8'})-[:RelType1 {prop2:'value9'}]->(:NodeType2 {prop3:'value10'})-[:RelType2 {prop4:'value11'}]->(:NodeType3 {prop5:'value12'})-[:RelType3 {prop6:'value13'}]->(:NodeType4 {prop7:'value14'}) 

MATCH path=(n:NodeType1 {prop1:'value1'})-[*]->(m:NodeType4 {prop7:'value7'}) 
CREATE (n)-[:RelType1 {prop2:'value15'}]->(:NodeType2 {prop3:'value16'})-[:RelType2 {prop4:'value17'}]->(:NodeType3 {prop5:'value18'})-[:RelType3 {prop6:'value19'}]->(m) 

圖表看起來是這樣的:

enter image description here

當我運行以下暗號:

MATCH path=(a:NodeType1 {prop1:"value1"})-[:RelType1]->(b)-[:RelType2]->(c)-[:RelType3]->(d) 
RETURN count(nodes(path)) 

我得到2 as out放。看來,nodes()犯規實際上返回路徑中的節點數目,但在返回結果行的只是數量,因爲如果我返回path

MATCH path=(a:NodeType1 {prop1:"value1"})-[:RelType1]->(b)-[:RelType2]->(c)-[:RelType3]->(d) 
RETURN path 

我得到的返回結果兩行:

enter image description here

現在我猜測如何在使用Neo4J遍歷API進行遍歷時獲得相同的輸出。我得到密碼中唯一節點的數量如下:

MATCH path=(a:NodeType1 {prop1:"value1"})-[:RelType1]->(b)-[:RelType2]->(c)-[:RelType3]->(d) 
RETURN size(collect(distinct a))+size(collect(distinct b))+size(collect(distinct c))+size(collect(distinct d)) 

以上查詢正確返回6

通過在路徑擴展器內部設置靜態計數器,每遍調用expand()就可以在遍歷API中完成相同操作。 (對此有任何更好的方法?)

public class MyPathExpander implements PathExpander{ 
    static int nodeCount = 0; 

    @Override 
    public Iterable expand(Path path, BranchState state) { 
     Node lastNode = path.endNode(); 

     nodeCount++; //**increment the count of nodes visited 

     if(lastNode.hasLabel(MyLabels.NodeType1)) 
      return lastNode.getRelationships(MyRelations.RelType1, Direction.OUTGOING); 
     else if (lastNode.hasRelationship(MyRelations.RelType1, Direction.INCOMING)) 
      return lastNode.getRelationships(MyRelations.RelType2, Direction.OUTGOING); 
     else if (lastNode.hasRelationship(MyRelations.RelType2, Direction.INCOMING)) 
      return lastNode.getRelationships(MyRelations.RelType3, Direction.OUTGOING); 
     else if (lastNode.hasRelationship(MyRelations.RelType3, Direction.INCOMING)) 
      return null; 
     return null; 
    } 
} 

但是我不能夠想到的辦法,這將告訴我的唯一路徑數,隨後遍歷過程中同時使用遍歷API(等效於上面RETURN count(nodes(path)))。我怎樣才能做到這一點?遍歷API不可能嗎?

PS:通過獨特的路徑,我指的是遍歷時訪問的節點的順序的唯一排列。例如,所有a-b-c,a-c-ba-b-c-d都是唯一的。

+0

'節點(路徑)'從路徑返回節點數組,而不是節點數...... –

回答

0

這查詢不返回唯一路徑的數量,但所有路徑的數量由查詢返回:

MATCH path=(a:NodeType1 {prop1:"value1"})-[:RelType1]->(b) 
      -[:RelType2]->(c)-[:RelType3]->(d) 
RETURN count(nodes(path)) 

如果你要計算在查詢中惟一的節點數量,你可以這樣做:

計算的唯一路徑的數量將是(對每個路徑計算其獨特的指紋,它不會是很難通過遍歷API重複)
MATCH path=(a:NodeType1 {prop1:"value1"})-[:RelType1]->(b) 
      -[:RelType2]->(c)-[:RelType3]->(d) 
UNWIND nodes(path) AS N 
RETURN count(distinct N) 

方式一:

MATCH path=(a:NodeType1 {prop1:"value1"})-[:RelType1]->(b) 
      -[:RelType2]->(c)-[:RelType3]->(d) 
WITH path, 
    REDUCE(acc="", x in nodes(path) | acc + id(x)) + 
    REDUCE(acc="", x in rels(path) | acc + id(x)) as uniID  
RETURN count(distinct uniID) 
+0

密碼體返回的路徑數和唯一路徑數是否會有所不同?我覺得兩者總是一樣。 – Mahesha999

+0

另外它的奇怪之處在於'RETURN節點(路徑)'返回路徑的數量,尤其是當'返回路徑,節點(路徑)'正確返回路徑時,節點'。然而,對於所有路徑,「返回路徑,計數(節點(路徑))」返回「路徑1」,即「1」。所以,我試圖通過類似這樣的方式獲得路徑中的節點數:'返回路徑,COUNT(UNWIND節點(路徑))'。它給出了錯誤。我知道我們可以這樣做:'返回路徑,長度(路徑)+ 1'爲節點數量= 1 +關係數量'長度(路徑)'返回關係數量。但是我們可以使用'COUNT(UNWIND nodes(path))'來做到這一點,這樣我們可以做COUNT(不同的UNWIND節點(路徑))' – Mahesha999