neo4j - How to write a Cypher query to check commutativity between nodes -
i need check commutativity between nodes. there 3 relationships across node tracked following: aabbca, aabcba, aacbba. seen every b , c node placed commute. below use query on how generate graph.
here graph:
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)
that generates this:
now identify commutative nodes, go ahead , filter on basis of relationship id 1 & 2, 1 & 3 , 2 & 3 using following query respective graphs:
match (a)-[r]->(b) 1 in r.id or 2 in r.id return a,r,b match (a)-[r]->(b) 1 in r.id or 3 in r.id return a,r,b match (a)-[r]->(b) 2 in r.id or 3 in r.id return a,r,b
the circled part of case 2, our example has 2 nodes, in generic case can have 1 (like see in case 1 & case 3) n number of nodes, n finite number.
now that's been said, want create cypher query check if such commutable node exists or not in graph , based on need fetch nodes , relationships graph using query this:
match (a)-[r]->(m)-[r]->(k)-[r]->[b], (b)-[s]->(k)-[s]->(m)-[s]->(a) r.id <> s.id , m returning minimum 1 node , k returning minimum 1 node return a,r,m,k,s,b k = m m = match (o)-[r]->(b1), (n)-[r]->(p)->[s]->(n) (b1 = b return b) or (n = m , p = m , n returning @ least 1 node , p returning @ least 1 node return n,r,p,s)
at point might not have defined constraints need represent above query correctly. can help?
update: solved case 1 & case 3 (which same type of condition), not generic solution. in generic solution case 2 have worked well.:
match (a)-[r]->(b)-[s]->(c)-[t]->(d) (1 in r.id or 2 in r.id) , (1 in s.id or 2 in s.id) , (1 in t.id or 2 in t.id) a,r,b,s,c,t,d match (a)-[r1]->(c)-[s1]->(b)-[t1]->(d) ( r <> r1 , (1 in r1.id or 2 in r1.id)) , (s<>s1 , (1 in s1.id or 2 in s1.id)) , (t<>t1 , (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) (3 in r.id or 2 in r.id) , (3 in s.id or 2 in s.id) , (3 in t.id or 2 in t.id) a,r,b,s,c,t,d match (a)-[r1]->(c)-[s1]->(b)-[t1]->(d) ( r <> r1 , (3 in r1.id or 2 in r1.id)) , (s<>s1 , (3 in s1.id or 2 in s1.id)) , (t<>t1 , (3 in t1.id or 2 in t1.id)) return a,r,r1,b,s,s1,c,t,t1,d
// nested loop through ids: unwind range(1,3) i1 i1 unwind range(i1+1,3) i2 i1, i2 // take pathways each pair of ids: match p1 = (n1:node)-[:transition*5 {id:[i1]}]->(n2:node), p2 = (n1:node)-[:transition*5 {id:[i2]}]->(n2:node) // take nodes of each path: i1, i2, nodes(p1) p1, nodes(p2) p2 i1, i2, p1, p2, // check whether nodes different: reduce(acc = [], x in range(0, size(p1)-1) | acc + [ { i:x, is: (p1[x] <> p2[x]) , (p1[x]['title'] <> p2[x]['title']) } ] ) iscomm i1, i2, p1, p2, // take nodes different: filter(pair in iscomm pair['is'] = true) iscomm return i1 id1, i2 id2, // convert map array: reduce(acc = [], pair in iscomm | acc + [ [ p1[pair['i']], p2[pair['i']] ] ] ) commutative
Comments
Post a Comment