def merge_nodes_and_transfer_edges( driver: GraphDatabase, surviving_id: str, deprecated_id: str, ) -> int: """ Transfer all edges from deprecated node to surviving node, then mark deprecated node as merged. Returns the number of edges transferred. """ with driver.session() as session: # Transfer outgoing edges result = session.run(""" MATCH (deprecated:Entity {id: $deprecated_id})-[r]->(target) WHERE NOT target.id = $surviving_id MATCH (surviving:Entity {id: $surviving_id}) CALL apoc.refactor.from(r, surviving) YIELD input, output RETURN count(*) AS transferred """, deprecated_id=deprecated_id, surviving_id=surviving_id) outgoing = result.single()["transferred"] # Transfer incoming edges result = session.run(""" MATCH (source)-[r]->(deprecated:Entity {id: $deprecated_id}) WHERE NOT source.id = $surviving_id MATCH (surviving:Entity {id: $surviving_id}) CALL apoc.refactor.to(r, surviving) YIELD input, output RETURN count(*) AS transferred """, deprecated_id=deprecated_id, surviving_id=surviving_id) incoming = result.single()["transferred"] # Mark deprecated node session.run(""" MATCH (e:Entity {id: $deprecated_id}) SET e.merged_into = $surviving_id, e.merged_at = datetime() """, deprecated_id=deprecated_id, surviving_id=surviving_id) return outgoing + incoming