2016-06-10 51 views
2

我需要檢查節點之間的交換性。整個節點有3種關係,如下所示:aabbca,aabcba,aacbba。現在可以清楚地看到,每個b和c節點放在一起他們通勤。下面我使用關於如何生成我的圖形的查詢。如何編寫一個Cypher查詢來檢查節點之間的交換性

這裏是我的圖:

CREATE (x1:Node {title:'a'}) 

CREATE (x2:Node {title:'a'}) 

CREATE (x3:Node {title:'b'}) 

CREATE (x4:Node {title:'b'}) 

CREATE (x5:Node {title:'c'}) 

CREATE (x6:Node {title:'a'}) 

CREATE (x1) - [:transition {id:[1]}] -> (x2) 

CREATE (x2) - [:transition {id:[1]}] -> (x3) 

CREATE (x3) - [:transition {id:[1]}] -> (x4) 

CREATE (x4) - [:transition {id:[1]}] -> (x5) 

CREATE (x5) - [:transition {id:[1]}] -> (x6) 

CREATE (x1) - [:transition {id:[2]}] -> (x2) 

CREATE (x2) - [:transition {id:[2]}] -> (x3) 

CREATE (x3) - [:transition {id:[2]}] -> (x5) 

CREATE (x5) - [:transition {id:[2]}] -> (x4) 

CREATE (x4) - [:transition {id:[2]}] -> (x6) 

CREATE (x1) - [:transition {id:[3]}] -> (x2) 

CREATE (x2) - [:transition {id:[3]}] -> (x5) 

CREATE (x5) - [:transition {id:[3]}] -> (x3) 

CREATE (x3) - [:transition {id:[3]}] -> (x4) 

CREATE (x4) - [:transition {id:[3]}] -> (x6) 

這產生這樣的:

enter image description here

我們清楚地識別交換節點,我繼續和過濾關係ID的基礎上, 1 & 2,1 & 3和2 & 3使用以下查詢我得到相應的圖表:

MATCH (a)-[r]->(b) WHERE 1 IN r.id OR 2 In r.id RETURN a,r,b 
MATCH (a)-[r]->(b) WHERE 1 IN r.id OR 3 In r.id RETURN a,r,b 
MATCH (a)-[r]->(b) WHERE 2 IN r.id OR 3 In r.id RETURN a,r,b 

殼體1: enter image description here 殼體2 :: enter image description here 殼體3: enter image description here

殼體2的圓圈部分,對於我們的例子僅具有2個節點,但在一般情況下,它可以有1 (就像我們在情況1中看到的那樣) & 情況3到N個節點,其中N是有限數。

現在我已經說過了,我想要創建一個密碼查詢來檢查這個可替換節點是否存在於圖中,並且基於我需要使用如下查詢從圖中獲取節點和關係:

MATCH (a)-[r]->(M)-[r]->(K)-[r]->[b], 
(b)-[s]->(K)-[s]->(M)-[s]->(a) 
WHERE r.id <> s.id 
AND M is returning minimum 1 node 
AND K is returning minimum 1 node 
RETURN a,r,M,K,s,b 

K = M 

M = MATCH (O)-[r]->(b1), (N)-[r]->(P)->[s]->(N) 
WHERE 
(b1 = b 
RETURN b) 
OR 
(N = M AND P = M 
AND N is returning at least 1 node 
AND P is returning at least 1 node 
RETURN N,r,P,s) 

在這一點上,我可能沒有明確地定義我的約束,但是我需要幫助的是正確地表示上述查詢。誰能幫忙?


更新: 我只解決了殼體1 &殼體3(它們基本上相同類型的條件),但這不是一個通用的解決方案。在一個通用的解決方案案例2本身也會有效。:

MATCH (a)-[r]->(b)-[s]->(c)-[t]->(d) 
WHERE (1 IN r.id OR 2 IN r.id) 
AND (1 IN s.id OR 2 IN s.id) 
AND (1 IN t.id OR 2 IN t.id) 
WITH a,r,b,s,c,t,d 
MATCH (a)-[r1]->(c)-[s1]->(b)-[t1]->(d) 
WHERE (r <> r1 AND (1 IN r1.id OR 2 IN r1.id)) AND 
(s<>s1 AND (1 IN s1.id OR 2 IN s1.id)) AND 
(t<>t1 AND (1 IN t1.id OR 2 IN t1.id)) 
RETURN a,r,r1,b,s,s1,c,t,t1,d 

MATCH (a)-[r]->(b)-[s]->(c)-[t]->(d) 
WHERE (3 IN r.id OR 2 IN r.id) 
AND (3 IN s.id OR 2 IN s.id) 
AND (3 IN t.id OR 2 IN t.id) 
WITH a,r,b,s,c,t,d 
MATCH (a)-[r1]->(c)-[s1]->(b)-[t1]->(d) 
WHERE (r <> r1 AND (3 IN r1.id OR 2 IN r1.id)) AND 
(s<>s1 AND (3 IN s1.id OR 2 IN s1.id)) AND 
(t<>t1 AND (3 IN t1.id OR 2 IN t1.id)) 
RETURN a,r,r1,b,s,s1,c,t,t1,d 

回答

1
// A nested loop through the IDs: 
UNWIND RANGE(1,3) as i1 WITH i1 
    UNWIND RANGE(i1+1,3) as i2 WITH i1, i2 

// Take a pathways for each pair of IDs: 
MATCH p1 = (N1:Node)-[:transition*5 {id:[i1]}]->(N2:Node), 
     p2 = (N1:Node)-[:transition*5 {id:[i2]}]->(N2:Node) 

// Take the nodes of each path: 
WITH i1, i2, 
    nodes(p1) as p1, 
    nodes(p2) as p2 

WITH i1, i2, p1, p2, 
    // Check whether the nodes are different: 
    REDUCE(acc = [], x in RANGE(0, size(p1)-1) | 
      acc + [ { i:x, 
         is: (p1[x] <> p2[x]) AND 
          (p1[x]['title'] <> p2[x]['title']) 
        } ] 
    ) as isComm 

WITH i1, i2, p1, p2, 
    // Take only those nodes that are different: 
    FILTER(pair in isComm WHERE pair['is'] = true) as isComm 

RETURN i1 as id1, i2 as id2, 
     // Convert a map to an array: 
     REDUCE(acc = [], pair in isComm | 
       acc + [ [ p1[pair['i']], 
         p2[pair['i']] 
        ] ] 
     ) as commutative 
相關問題