let's have graph network shown here:
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
Post a Comment