2016-06-10 5 views
2

Ich muss Kommutativität zwischen den Knoten überprüfen. Es gibt 3 Beziehungen über den Knoten, die wie folgt verfolgt werden: aabbca, aabcba, aacbba. Jetzt ist deutlich zu sehen, dass wo jeder b und c Knoten zusammen pendelt sie pendeln. Im Folgenden verwende ich die Abfrage, wie ich mein Diagramm erzeuge.Wie schreibe ich eine Cypher-Abfrage zur Überprüfung der Kommutativität zwischen den Knoten

Hier ist mein Diagramm:

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) 

, die ungefähr so ​​erzeugt:

enter image description here

nun den kommutativen Knoten eindeutig zu identifizieren, ich gehe voran und Filter auf Basis der Beziehung id 1 & 2, 1 & 3 und 2 & 3 mit folgender Abfrage bekomme ich die entsprechenden Graphen:

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 

Fall 1: enter image description here Fall 2 :: enter image description here Fall 3: enter image description here

Die eingekreisten Teil Fall 2, für unser Beispiel nur zwei Knoten hat, aber in einem allgemeinen Fall ist es kann 1 (wie wir in Fall 1 & Fall 3 sehen) zu N Anzahl der Knoten, wobei N eine endliche Zahl ist.

Nun, das wurde gesagt, ich möchte eine Chiffre Abfrage erstellen, die prüfen wird, ob solche austauschbare Knoten im Diagramm vorhanden ist oder nicht und basierend darauf muss ich Knoten und Beziehungen aus einem Diagramm mit einer Abfrage wie folgt abrufen:

An diesem Punkt habe ich meine Einschränkungen möglicherweise nicht klar definiert, aber was ich brauche, ist, die obige Abfrage korrekt darzustellen. Kann jemand helfen?


Update: Ich löste nur für den Fall 1 & Fall 3 (das ist im Grunde dieselbe Art von Zustand sind), aber dies ist nicht eine allgemeine Lösung. In einer generischen Lösung Fall 2 wäre auch .:

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 

Antwort

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 
gearbeitet haben