Try using OPTIONAL and also distinct.
Explanation: According to neo4j concept of cardinality, if we have several matches, we will get a row for each one of them. Therefore, if several nodes are connected to existingNode we will get several rows as a result, one for each connected node. The existingNode will repeat in all of them, causing next steps regarding to it, to be duplicated. In our case the new connection step will be preformed multiple times.
Without the OPTIONAL if there are zero nodes connected to it, we will get zero rows, which is the other problem.
So when using the OPTIONAL, after the DELETE step we have multiple existingNode, as the number of existingRelationships, but at least one, thanks to the OPTIONAL. We still need to use distinct to avoid creating multiple relationships to m:
MATCH (existingNode:Person {
key: 'A'
})
WITH existingNode
OPTIONAL MATCH (existingNode)-[existingRelationships]->()
DELETE existingRelationships
WITH distinct existingNode as existingNode
MATCH (m:Movie {key: 'B'})
WITH existingNode, m
CREATE (existingNode)-[:ACTED_IN]->(m)
RETURN existingNode, m
It works well for the sample data with relationships to delete:
MERGE (a:Person{key: 'A'})
MERGE (b:Movie{key: 'B'})
MERGE (c:Node{key: 'C'})
MERGE (d:Node{key: 'D'})
MERGE (e:Node{key: 'E'})
MERGE (a)-[:POINTS]-(c)
MERGE (a)-[:POINTS]-(d)
MERGE (a)-[:POINTS]-(e)
And another one without relationships to delete:
MERGE (a:Person{key: 'A'})
MERGE (b:Movie{key: 'B'})
For both cases it returns:
╒══════════════╤═══════════╕
│"existingNode"│"m" │
╞══════════════╪═══════════╡
│{"key":"A"} │{"key":"B"}│
└──────────────┴───────────┘