So I am right now noticing a behaviour that I can not make sense of from the documentation.
Let's say I have a node D1
of type Dataset
and I have 3 other nodes C1
, C2
, C3
of type CompanyDepartment
attached to it.
Now I want to do two things
- Update node
D1
- Detach Delete
C1
,C2
,C3
A simple query that works is:
MATCH (d: Dataset { id: "D1" })
SET d.updatedAt = datetime()
WITH d
OPTIONAL MATCH (d)-[r:ENTITY]->(draft_entities)
DETACH DELETE draft_entities
But I am dealing with a lot of entities, so I want to put batching into it so I decided to use an APOC function
MATCH (d: Dataset { id: "D1" })
SET d.updatedAt = datetime()
WITH d
CALL apoc.periodic.iterate(
' WITH $d as d
OPTIONAL MATCH (d)-[r:ENTITY]->(draft_entities)
RETURN draft_entities
',
'
DETACH DELETE draft_entities // Or we can also just do DELETE r for testing
',
{ batchSize: 100, parallel: false, params: { d: d } }
) YIELD batches AS draft_batches, total AS draft_total
RETURN draft_total
But when I run the query like this it gets stuck, it keeps running forever. From a lot of debugging it seems to me that when we SET
something on node, it blocks it blockes the deletion for it's outgoing relations as well. We can update them but not delete them.
Is my assumption correct? If yes can you point me to the documentation of that explains this difference in behaviour for APOC? Intutively, updating a node should not lock the outgoing relations in any way. EXPLAIN
isn't showing anything meaningful as it's an APOC procedure call.
I am using Neo4j 5.23. This can be reproduced using Neo4j browser UI, but we also get the same behaviour using javascript driver.
Ideally I want to do the SET
and DELETE
in two different queries in the same transaction but the issue is the same.
The data can be created for testing these queries using:
CREATE (d:Dataset {id: "D1", name: "Dataset A"})
CREATE (cd1:CompanyDepartment {id: "CD1", name: "Department 1"})
CREATE (cd2:CompanyDepartment {id: "CD2", name: "Department 2"})
CREATE (cd3:CompanyDepartment {id: "CD3", name: "Department 3"})
CREATE (d)-[:ENTITY]->(cd1)
CREATE (d)-[:ENTITY]->(cd2)
CREATE (d)-[:ENTITY]->(cd3)
RETURN d, cd1, cd2, cd3