// Cypher-Anweisungen für Neo4j 5 (mit v5.3 getestet) // 14.3.1.1 Knoten CREATE (:Bauobjekt:Flagge) MATCH (n) RETURN * CREATE (:Landnutzung:Weideland {name: 'Kuhwiese'}); CREATE (:Landnutzung:Weideland {name: 'Inselwiese'}); CREATE (:Landnutzung:Wald {name: 'Räuberwald'}); CREATE (:Landnutzung:Bebauung {name: 'Hütte'}); CREATE (:Landnutzung:Sumpf:Moor {name: 'Südwestsumpf'}); CREATE (:Landnutzung:Wasser:See {name: 'Silbersee'}); MATCH (n:Weideland) RETURN id(n), n.name MATCH (n) WHERE n.name = 'Hütte' OR n.name = 'Silbersee' RETURN n.name, labels(n) // Label Bauobjekt der Hütte hinzufügen: MATCH (n) WHERE n.name = 'Hütte' SET n:Bauobjekt RETURN labels(n) // Attributwerte hinzufügen: MATCH (o:Flagge) SET o.name = 'Inselfahne'; MATCH (o:Flagge) WHERE o.name = 'Inselfahne' SET o.errichtung = date("2021-10-27"), o.national = false; MATCH (b:Bauobjekt) SET b.höhe = 10.5 RETURN b.name, b.höhe, b.national, b.errichtung; // Label löschen: MATCH (n) WHERE n.name = 'Südwestsumpf' REMOVE n:Moor; // Attribut löschen: MATCH (n) WHERE n.name = 'Hütte' REMOVE n.höhe; // MATCH (n) DELETE n // nicht ausführen! // 14.2.1.2 Kanten MATCH (s:Landnutzung) WHERE s.name = 'Kuhwiese' MATCH (z:Landnutzung) WHERE z.name = 'Räuberwald' CREATE (s)-[r:TOUCHES]->(z); MATCH (s:Landnutzung) WHERE s.name = 'Kuhwiese' MATCH (z:Landnutzung) WHERE z.name = 'Südwestsumpf' CREATE (s)-[r:TOUCHES]->(z); MATCH (s:Landnutzung) WHERE s.name = 'Räuberwald' MATCH (z:Landnutzung) WHERE z.name = 'Südwestsumpf' CREATE (s)-[r:TOUCHES]->(z); MATCH (s:Landnutzung) WHERE s.name = 'Inselwiese' MATCH (z:Landnutzung) WHERE z.name = 'Hütte' CREATE (s)-[r:TOUCHES]->(z); MATCH (s:Landnutzung) WHERE s.name = 'Silbersee' MATCH (z:Landnutzung) WHERE z.name IN ['Kuhwiese','Räuberwald','Inselwiese'] CREATE (s)-[r:TOUCHES]->(z); MATCH (c:Landnutzung) WHERE c.name = 'Inselwiese' MATCH (e:Bauobjekt) WHERE e.name = 'Inselfahne' CREATE (c)-[r1:CONTAINS]->(e), (e)-[r2:WITHIN]->(c); MATCH (s)-[r]->(z) RETURN s.name, type(r), z.name MATCH (n1)-[r]-(n2) WHERE n1.name = 'Inselwiese' RETURN type(r), n2.name WITH 'Räuberwald' AS queryname MATCH (n1)-[TOUCHES]-(n2) WHERE n1.name = queryname RETURN n2.name ORDER BY n2.name // Korrektur: r.type -> type(r) // ab v4.4: keine implizite Gruppierung bei Funktionsaufrufen -> Ergänzung um WITH-Klausel MATCH ()-[r]->() WITH type(r) AS t RETURN t, count(*) ORDER BY t // 14.3.1.3 Punktdaten // ab v4.4: distance -> point.distance WITH point({x:10, y:11}) AS flagge, point({x:10, y:19}) AS baum RETURN flagge, baum, point.distance(flagge,baum) AS dist WITH point({x:10, y:11, z:10.5}) AS flagge, point({x:10, y:19, z:7}) AS baum RETURN flagge, baum, point.distance(flagge,baum) AS dist RETURN point({x: 528137.95, y: 6070678.66, srid: 25832}) WITH point({x: 9.7358, y: 52.3803, crs: 'WGS-84'}) AS h, point({longitude: 8.2275, latitude: 53.1375}) AS ol RETURN h, ol, point.distance(h,ol)/1000.0 AS dist_km WITH point({x: 9.7358, y: 52.3803, z: 55, crs: 'WGS-84-3D'}) AS h, point({longitude: 8.2275, latitude: 53.1375, height: 5}) AS ol RETURN ol.srid, ol.crs, ol.z, ol.height, point.distance(h,ol)/1000.0 AS dist_km // 14.3.1.4 Datenimport, Integritätsbedingungen und Indexe LOAD CSV WITH HEADERS FROM "https://www.geodbs.de/downloads/olnetz_nodes.csv" AS line CREATE (:StrKnoten {nodeid: toInteger(line.id), pos: Point({x: toFloat(line.x), y: toFloat(line.y)} )}) // ab v4.4: ON -> FOR, ASSERT -> REQUIRE CREATE CONSTRAINT strkn_nid_uq FOR (n:StrKnoten) REQUIRE n.nodeid IS UNIQUE SHOW CONSTRAINTS SHOW INDEXES LOAD CSV WITH HEADERS FROM "https://www.geodbs.de/downloads/olnetz_links.csv" AS line MATCH (s:StrKnoten) WHERE s.nodeid = toInteger(line.start) MATCH (z:StrKnoten) WHERE z.nodeid = toInteger(line.end) CREATE (s)-[r:CONNECTS{ linkid: toInteger(line.id), name: line.name, type: toInteger(line.type) }]->(z) CREATE CONSTRAINT connect_lid_uq FOR (r:CONNECTS) REQUIRE r.linkid IS UNIQUE CREATE INDEX connect_name_ix FOR ()-[r:CONNECTS]-() ON (r.name) MATCH p=()-[r:CONNECTS]->() WHERE r.name = 'Hauptstraße' RETURN p PROFILE MATCH p=()-[r:CONNECTS]->() WHERE r.name = 'Hauptstraße' RETURN p // 14.3.2.1 Bestimmung von Nachbarn // v5: keine Pfad-Ausdruck in RETURN, stattdessen: MATCH p = (s)-[r1]-(z)-[r2]-(n) WHERE r1.name = 'Hauptstraße' AND r2.name <> 'Hauptstraße' RETURN p // oder: MATCH hs = (s)-[r1]-(z) MATCH ns = (z)-[r2]-(n) WHERE r1.name = 'Hauptstraße' AND r2.name <> 'Hauptstraße' RETURN hs, ns MATCH p=(s)-[r1]-(z)-[*1..2]-(n) WHERE r1.name = 'Hauptstraße' RETURN p MATCH (s:StrKnoten) WHERE s.nodeid = 1345 MATCH (d:StrKnoten) WHERE d.nodeid = 6436 RETURN exists( (s)-[*..60]-(d) ) MATCH (s:StrKnoten) WHERE s.nodeid = 1345 MATCH p = (s)-[*..20]-(d) RETURN d.nodeid, length(p) ORDER BY d.nodeid, length(p) MATCH (s:StrKnoten) WHERE s.nodeid = 1345 MATCH p = (s)-[*..20]-(d) RETURN DISTINCT d.nodeid, min(length(p)), count(p) ORDER BY d.nodeid MATCH (s:StrKnoten) WHERE s.nodeid = 1345 MATCH p = (s)-[*..6]-(d) RETURN DISTINCT d.nodeid, min(length(p)) AS len, count(p) ORDER BY len LIMIT 6 // 14.3.2.3 Kürzeste Wege MATCH (s:StrKnoten) WHERE s.nodeid = 1345 MATCH (d:StrKnoten) WHERE d.nodeid = 6436 MATCH p = shortestPath((s)-[*0..60]-(d)) RETURN p, length(p); MATCH (s:StrKnoten) WHERE s.nodeid = 1345 MATCH (d:StrKnoten) WHERE d.nodeid = 6436 MATCH p = allShortestPaths((s)-[*0..60]-(d)) RETURN length(p), count(p); MATCH (s:StrKnoten) WHERE s.nodeid = 1345 MATCH (d:StrKnoten) WHERE d.nodeid = 6436 MATCH p = allShortestPaths((s)-[*0..60]-(d)) UNWIND relationships(p) AS link WITH p AS path, startNode(link) AS n1, endNode(link) AS n2 RETURN path, sum(point.distance( n1.pos,n2.pos )) AS dist_m // 14.3.3.1 Räumlicher Index // ab v.5 POINT ersetzt BTREE CREATE POINT INDEX strkn_pos_ix FOR (n:StrKnoten) ON (n.pos) OPTIONS {indexConfig: {`spatial.cartesian.min`: [0.0, 0.0], `spatial.cartesian.max`: [24000.0, 28000.0]}} MATCH (s:StrKnoten) WHERE s.nodeid = 6436 MATCH (n:StrKnoten) WHERE point.distance(n.pos, s.pos) <= 1000 RETURN n.nodeid, point.distance(n.pos, s.pos) AS dist ORDER BY dist PROFILE MATCH (s:StrKnoten) WHERE s.nodeid = 6436 MATCH (n:StrKnoten) WHERE point.distance(n.pos, s.pos) <= 1000 RETURN n.nodeid, point.distance(n.pos, s.pos) AS dist ORDER BY dist // ab v4.4: rmin < n.pos < rmax -> point.withinBBox(n.pos,rmin,rmax) MATCH (s:StrKnoten) WHERE s.nodeid = 6436 WITH point({x: s.pos.x-1000, y: s.pos.y-1000}) AS rmin, point({x: s.pos.x+1000, y: s.pos.y+1000}) AS rmax MATCH (n:StrKnoten) WHERE point.withinBBox(n.pos,rmin,rmax) RETURN n PROFILE MATCH (s:StrKnoten) WHERE s.nodeid = 6436 WITH point({x: s.pos.x-1000, y: s.pos.y-1000}) AS rmin, point({x: s.pos.x+1000, y: s.pos.y+1000}) AS rmax MATCH (n:StrKnoten) WHERE point.withinBBox(n.pos,rmin,rmax) RETURN n