0

I'm trying to implement stream ordering on a small water network using cypher in neo4j. I've recreated the network in the below image and I want to add the stream order number on the link.

enter image description here

I first of all tried using where statements but this doesn't seem to like the <> and nothing is set on the network after the order 2 links are worked out.

match (n:StrahlerTest)-[:LINK]->(o:StrahlerTest)<-[:LINK]-(p:StrahlerTest) 
where not (n)<-[:LINK]-() 
with n,o,p
where not (p)<-[:LINK]-()
with n,o,p
match (o)-[r:LINK]->()
set r.strahler_number = 2
with n
match (:StrahlerTest)-[:LINK{strahler_number:2}]->(o:StrahlerTest)<-[r:LINK]-(p:StrahlerTest)
with o, r
match (o)-[r2:LINK]->(q)
where r.strahler_number <> 2 set r2.strahler_number = 2
with o, r
match (o)-[r2:LINK]->(q)
where r.strahler_number = 2 set r2.strahler_number = 3
with q
match (:StrahlerTest)-[:LINK{strahler_number:3}]->(o:StrahlerTest)<-[r:LINK]-(p:StrahlerTest)
with o, r
match (o)-[r2:LINK]->(q)
where r.strahler_number <> 3 set r2.strahler_number = 3
with o, r
match (o)-[r2:LINK]->(q)
where r.strahler_number = 3 set r2.strahler_number = 4
with q
match (:StrahlerTest)-[:LINK{strahler_number:4}]->(o:StrahlerTest)<-[r:LINK]-(p:StrahlerTest)
with o, r
match (o)-[r2:LINK]->(q)
where r.strahler_number <> 4 set r2.strahler_number = 4

Next I tried Foreach, but a match statement can not be used with a foreach statement.

match (n:StrahlerTest)-[:LINK]->(o:StrahlerTest)<-[:LINK]-(p:StrahlerTest) 
where not (n)<-[:LINK]-() 
with n,o,p
where not (p)<-[:LINK]-()
with n,o,p
match (o)-[r:LINK]->()
set r.strahler_number = 2
with [2,3,4] as num
foreach (n in num | match (:StrahlerTest)-[:LINK{strahler_number:n}]->(o:StrahlerTest)<-[r:LINK]-(:StrahlerTest))
with o, r, n
match (o)-[r2:LINK]->()
set r2.strahler_number = 
    case r2.strahler_number
    when r.strahler_number <> n
    then n
    else n+1 end

Finally I tried unwind. It worked up to setting the first set of order three links (so directly following two order 2 links) but did not provide the correct value for the order 3 link which follows another order 3 link (when the order 1 link joins the network).

match (n:StrahlerTest)-[:LINK]->(o:StrahlerTest)<-[:LINK]-(p:StrahlerTest) 
where not (n)<-[:LINK]-() 
with n,o,p
where not (p)<-[:LINK]-()
with n,o,p
match (o)-[r:LINK]->()
set r.strahler_number = 2
with [2,3,4] as num
unwind num as n 
match (:StrahlerTest)-[:LINK{strahler_number:n}]->(o:StrahlerTest)<-[r:LINK]-(:StrahlerTest)
with o, r, n
match (o)-[r2:LINK]->()
set r2.strahler_number = 
    case r2.strahler_number
    when r.strahler_number <> n
    then n
    else n+1 end

Hopefully that is clear. Any ideas / advice on how to get this to work would be much appreciated.

SAB
  • 175
  • 17

1 Answers1

0

Turns out I was just getting the syntax slightly wrong. This works

match (n:StrahlerTest)-[:LINK]->(o:StrahlerTest)<-[:LINK]-(p:StrahlerTest) 
where not (n)<-[:LINK]-() 
with n,o,p
where not (p)<-[:LINK]-()
with n,o,p
match (o)-[r:LINK]->()
set r.strahler_number = 2
with [2,3,4] as num
unwind num as n 
    match (:StrahlerTest)-[:LINK{strahler_number:n}]->(o:StrahlerTest)<-[r:LINK]-(:StrahlerTest)
        with o, r, n
        match (o)-[r2:LINK]->()
        set r2.strahler_number = 
            case 
            when r.strahler_number <> n
            then n
            else n+1 end
SAB
  • 175
  • 17