I have a node-link model ( which is a graph ) of an electricity grid in Neo4j, so this should fit like a glove.
The nodes and links are objects of their own, which are traversable in an abstract manner.
Link has a starting node (:Link) – [:begint_bij] –> (:Node) and an ending node (:Link) – [:eindigt_bij] –> (:Node)
Every :Node and :Link has references to one or more objects. Links and Nodes are uniquely defined by their references in this model.
The model is generated by the object-oriented GIS model and because of the generating method ( which I have no influence on ) redundant Node Link (pairs) are in the dataset.
In the picture we see a cloud of Nodes ( purple ) and Links ( green ) surrounding an electricity cable.
In the detail you can see the redundant pairs clearly with a pattern:
A Node-Link pair where the Node has only relationship to ( cables, gisreferences and links ) and the link has only relationships to ( cables, gisreferences and nodes )
For removing the redundant Node-Link pairs I have come up with this query:
call apoc.periodic.iterate (
" MATCH (fld:e_lv_function_cable ) where not exists (fld.done) Return fld",
" match (fld) - [:GenObject] - (fn:Node)
match (fn) - [:begint_bij] - (l1:Link)
with [(fn) - - (obj1) | labels(obj1)] AS conn1, [(l1) - - (obj2) | labels(obj2)] AS conn2, fn, l1, fld
where all( lb1 IN conn1 where lb1[0] in ['e_lv_function_cable','GisReference','Link'] )
and all( lb2 IN conn2 where lb2[0] in ['e_lv_function_cable','GisReference','Node'] )
with l1, fn, fld
match (l1) - [:eindigt_bij] - (n2)
match (l2:Link) - [r] - (fn) - [:begint_bij] - (l1)
Call apoc.do.when (
n2 is not null and l2 is not null and r is not null,
'Call apoc.create.relationship (l2, type(r), {}, n2) YIELD rel Detach Delete l1, fn',
'',
{n2: n2, l2: l2, r: r, l1: l1, fn: fn}) YIELD value
with fld
set fld.done=true
", {batchSize:100, parallel:false}) yield batches, total return batches, total
And it does the job.
However in a few cases I get an error ( in the debug log ):
Failed to invoke procedure apoc.do.when
: Caused by: org.neo4j.graphdb.NotFoundException: Node is deleted and cannot be used to create a relationship
And sometimes:
Failed to invoke procedure apoc.do.when
: Caused by: java.lang.IllegalStateException: Kernel API returned non-existent relationship type: -1
And it almost makes sense to me.
Can anyone please:
- (better) explain to me what is causing this, and
- Point me t a query that does the job 100%
Thx.