Neo4j Cypher - Query partial fixed route and partial variable route -


let's have graph network shown here: graph network

i can cypher query using like

match (a:a)-[]->(b:b)-[]->(c:c)-[]-(d1:d), (a)-[]->(b)-[]->(c)-[]-(d2:d), (a)-[]->(b)-[]->(c)-[]-(d3:d), (a)-[]->(b)-[]->(c)-[]-(d4:d), d1.val = '1' , d2.val = '2' , d3.val ='3', d4.val = '4' return a, b, c, d1, d2, d3, d4 

is there way simplify query, without explicitly rewriting relationship on , on again, identical. trying find every relation has d values expecting, large list in clause appropriate.

edit: sample data based on answer below

create (a1:a {name: 'a1'}) create (b1:b {name: 'b1'}) create (c1:c {name: 'c1'}) create (d1:d {name: 'd1', val: 1}) create (d2:d {name: 'd2', val: 2}) create (d3:d {name: 'd3', val: 3}) create (d4:d {name: 'd4', val: 4}) create (a1)-[:next]->(b1) create (b1)-[:next]->(c1) create (c1)-[:next]->(d1) create (c1)-[:next]->(d2) create (c1)-[:next]->(d3) create (c1)-[:next]->(d4) create (a2:a {name: 'a2'}) create (b2:b {name: 'b2'}) create (c2:c {name: 'c2'}) create (a2)-[:next]->(b2) create (b2)-[:next]->(c2) create (c2)-[:next]->(d1) create (c2)-[:next]->(d2) create (a3:a {name: 'a3'}) create (b3:b {name: 'b3'}) create (c3:c {name: 'c3'}) create (a3)-[:next]->(b3) create (b3)-[:next]->(c3) create (c3)-[:next]->(d1) create (c3)-[:next]->(d2) create (c3)-[:next]->(d3) create (c3)-[:next]->(d4) return * 

so query should result in a1-->b1-->c1-->d1,d2,d3,d4 , a3-->b3-->c3-->d1,d2,d3,d4 since a2-->b2--c2 links d1,d2 , not d3,d4 should not in result.

the beginning of path same, don't need repeat it. then, based on list of values, want check if can find d each , every 1 of them: job all.

mixing that, get:

match (a:a)-->(b:b)-->(c:c)-->(d:d) d.val in {values} a, b, c, collect(d) dlist all(value in values any(d in dlist d.val = value)) return a, d, c, dlist 

however, if n number of values, that's o(n^2) algorithm because of second where.

let's collect values of nodes while collecting nodes themselves, avoid double loop , turn o(n) algorithm:

match (a:a)-->(b:b)-->(c:c)-->(d:d) d.val in {values} a, b, c, collect(d) dlist, collect(distinct d.val) dvalues all(value in values value in dvalues) return a, d, c, dlist 

assuming list of values passed parameter contains distinct values, can change o(1) algorithm comparing size of input list , distinct values found:

match (a:a)-->(b:b)-->(c:c)-->(d:d) d.val in {values} a, b, c, collect(d) dlist, collect(distinct d.val) dvalues size({values}) = size(dvalues) return a, d, c, dlist 

because dvalues ⊂ values, if 2 sets have same size, they're equal.

if d.val globally unique, or @ least unique d nodes connected single c, can further simplified:

match (a:a)-->(b:b)-->(c:c)-->(d:d) d.val in {values} a, b, c, collect(d) dlist size({values}) = size(dlist) return a, d, c, dlist 

if values globally unique, query faster unicity constraint index values:

create constraint on (d:d) assert d.val unique 

Comments