Martin Preusse
Martin Preusse

Reputation: 9369

Call APOC procedure in apoc.periodic.iterate

I am trying to add new relationships based on a property of existing relationships with the apoc.create.relationship function:

:auto CALL apoc.periodic.iterate(
    "MATCH (source:Entity)-[r:TEMP_RELATION]->(target:Entity) RETURN source, r, target",
    "CALL apoc.create.relationship(source, r.`Interaction-type`, r, target) YIELD rel RETURN rel",
    {batchSize:5}
    );

When I run this query I get Java heap errors (max heap is 8g). It looks like iterate is not actually iterating but loading too much into memory. I use Neo4j 4.4.8 on a Mac (M1).

Any ideas why there is a memory leak here?

Upvotes: 0

Views: 1260

Answers (1)

Michael Hunger
Michael Hunger

Reputation: 41706

Since neo4j 4 the behavior changed, when you pass a node or relationship to a separate transaction/statement it carries along it's own transaction where it originated from.

So all updates are accumulated on that original transaction. To avoid that you have to "rebind" the nodes and rels best by returning id(n) as id or id(r) as relId

Then you can re-match the node and rels in the update statement: WHERE id(n) = id and use it from there. In your example:

:auto CALL apoc.periodic.iterate(
"MATCH (source:Entity)-[r:TEMP_RELATION]->(target:Entity) RETURN id(source) as sId, properties(r) as props, r.`Interaction-type` as type, id(target) as tId",
"MATCH (source), (target) where id(source) = sId AND id(target) = tId 
 CALL apoc.create.relationship(source, type, props, target) YIELD rel RETURN count(*)",
{batchSize:10000}
);

Upvotes: 2

Related Questions