2014-12-01 65 views
3

假設我有一個圖形,其中節點是紅色或綠色。我從一個紅色節點開始,我希望獲得連接到我的起始節點的所有其他紅色節點,只通過綠色節點。在限制節點類型時匹配可變長度路徑

舉例來說,如果我有以下圖表:

(R1) 
/ \ 
(G1) (G3) 
|  | 
(G2) (R3) 
|  | 
(G5) (G4) 
|  | 
(R2) (R4) 

我希望得到以下結果集:

R1, R2 
R1, R3 

如何編寫查詢任何想法?

感謝,

編輯: 要創建圖:

CREATE (r1:Red{label: "R1"})-[:foo]->(g1:Green{label: "G1"})-[:foo]->(g2:Green{label: "G2"})-[:foo]->(g5:Green{label:"G5"})-[:foo]->(r2:Red{label: "R2"}), 
    (r1)-[:foo]->(g3:Green{label: "G3"})-[:foo]->(r3:Red{label: "R3"})-[:foo]->(g4:Green{label: "G4"})-[:foo]->(r4:Red{label: "R4"}); 

我試過下面的查詢,但它給我回節點R4,這是我不想要的。

MATCH (r1:Red{label:'R1'})-[:foo*]->(green:Green)-->(other_red) RETURN r1, green, other_red 

回答

2

這裏是一個解決方案:

MATCH p = (r1:Red {label:'R1'})-[:foo*]->(green:Green)-[:foo]->(other_red:Red) 
WITH r1, green, other_red, [n IN nodes(p) WHERE 'Red' in labels(n) | n] as redNodes 
WHERE length(redNodes) = 2 
RETURN r1, green, other_red 

這確保只有第一紅色節點採取通過保持僅包含2個紅色節點(r1other_red)的路徑。

0

您的數據設置:

CREATE (r1 {label: "R1"})-[:foo]->(g1 {label: "G1"})-[:foo]->(g2 {label: "G2"})-[:foo]->(r2 {label: "R2"}), 
     (r1)-[:foo]->(g3 {label: "G3"})-[:foo]->(r3 {label: "R3"})-[:foo]->(g4 {label: "G4"})-[:foo]->(r4 {label: "R4"}); 

現在,這裏是你的查詢:

MATCH (r1 { label: "R1"})-[:foo*1..3]->(target) 
WHERE target.label =~ "R.*" 
RETURN r1.label, target.label; 

此查詢使用可變長度路徑([:foo*1.3])指定的路徑必須是至少一個步長不超過3步。然後,我基於標籤以「R」開頭的節點進行過濾。這給出了正確的結果,否則G1,G2和G3也將在結果集中,因爲它們在該跳數內。

+0

有什麼辦法來限制路徑的中間節點,而不是限制它的長度?有些情況下,另一個紅色節點通過多於3個綠色節點連接,並增加您的情況下路徑的長度將捕獲不需要的紅色。 – 2014-12-01 21:27:44

+0

您可以通過使其成爲'[:foo * 1 ..]'來移除長度限制。通過使用'WHERE'子句,可以進一步限制中間節點。你想要什麼限制?所以是的,你可以做到這兩個......答案是解決你在問題中提供的內容。 – FrobberOfBits 2014-12-01 21:35:11

+0

如果我刪除長度約束,節點R4將返回,我不想要。我更新了我的例子,以更具代表性。重申一下,我想從一個節點開始,通過綠色節點遍歷傳出關係,直到遇到第一個紅色節點。 – 2014-12-01 21:43:48