neo4jcypherneo4j-apoc

Renaming Labels of relationships in Neo4j using parallel processing


I have a lot of relationships in my Neo4j Database for which I have to rename labels. As the number is quite high (close to 13 million), I am processing parallelly for faster execution. I believe my Cypher Query is correct, but a weird error is getting thrown by the system:

Error:

{
  "Invalid input 'CALL': expected\r\n  "!="\r\n  "%"\r\n  "*"\r\n  "+"\r\n  "-"\r\n  "/"\r\n  "::"\r\n  "<"\r\n  "<="\r\n  "<>"\r\n  "="\r\n  "=~"\r\n  ">"\r\n  ">="\r\n  "AND"\r\n  "AS"\r\n  "CONTAINS"\r\n  "ENDS"\r\n  "IN"\r\n  "IS"\r\n  "OR"\r\n  "STARTS"\r\n  "XOR"\r\n  "^"\r\n  "||" (line 3, column 6 (offset: 83))\r\n"     CALL apoc.refactor.rename.type("OLD_LABEL", "NEW_LABEL",r)"\r\n      ^": 1328
} 

I ran this cypher query.

Cypher Query:

CALL apoc.periodic.iterate(
    'MATCH ()-[r:OLD_LABEL]->() RETURN r',
    'WITH r LIMIT 10000
     UNWIND r
     CALL apoc.refactor.rename.type("OLD_LABEL", "NEW_LABEL",r)',
    { batchSize: 10000, parallel: true }
)

Is there something I am missing out or doing it wrong? Also what can be other possible ways to do this job?


Solution

  • Some misunderstandings in general

    WITH r
    

    doesn't produce a collection, so trying to UNWIND will not work here.

    Secondly, UNWIND needs to alias the resulting element, like :

    UNWIND batch AS item
    

    However, the most efficient way for your use case is to process per batch and use batchMode = BATCH_SINGLE https://neo4j.com/docs/apoc/current/overview/apoc.periodic/apoc.periodic.iterate/#_batch_mode_batch_single

    CALL apoc.periodic.iterate(
        'MATCH ()-[r:OLD_LABEL]->() RETURN r',
        'CALL apoc.refactor.rename.type("OLD_LABEL", "NEW_LABEL", [x IN $_batch | x.r] )',
        { batchSize: 10000, parallel: true, batchMode: 'BATCH_SINGLE' }
    )