Search code examples
neo4jcypherneo4j-apocapoc

Splitting string with apoc.periodic.iterate


I am encountering errors when including a function to split a string inside apoc.periodic.iterate in Neo4j. Namely, here is my query which runs fine:

WITH collect(file.URL) AS fileURLs
UNWIND fileURLs AS fileURL
CALL apoc.periodic.iterate(
'
CALL apoc.load.csv($url) YIELD map AS csv
RETURN csv
',
'
WITH round(toFloat(csv.dendrogram_height),3,"HALF_UP") as height, csv.gene_name as gene, csv.event_no as event, csv.samples as sp, round(toFloat(csv.median_ge),3,"HALF_UP") as me, csv.no_of_samples as no_s, csv.leaf_status as leaf, csv.patients as pts, csv.no_of_uniq_patients as no_pt, round((toFloat(csv.log2fc)),3,"HALF_UP") as log2, round(toFloat(csv.padj_deseq2),3,"HALF_UP") as padj, csv.up_or_down as up
CREATE (:Expression:Primary {name: gene, event_no: event, dendrogram_height: height, samples: sp, median_exp: me, no_of_samples: no_s, leaf_status: leaf, patients: pts, no_of_unique_patients: no_pt, log2fc: log2, padj_deseq2: padj, up_or_down: up});
',
{batchSize:10000,parallel:true,params:{url:fileURL}}) YIELD batches, total
RETURN batches, total;

But when I include the function split (or apoc.text.split for that matter) in the WITH statement, namely,

MATCH (file:File) WITH file
WITH collect(file.URL) AS fileURLs
UNWIND fileURLs AS fileURL
CALL apoc.periodic.iterate(
'
CALL apoc.load.csv($url) YIELD map AS csv
RETURN csv
',
'
WITH round(toFloat(csv.dendrogram_height),3,"HALF_UP") as height, csv.gene_name as gene, csv.event_no as event, csv.samples as sp, round(toFloat(csv.median_ge),3,"HALF_UP") as me, csv.no_of_samples as no_s, csv.leaf_status as leaf, split(csv.patients,',') as pts, csv.no_of_uniq_patients as no_pt, round((toFloat(csv.log2fc)),3,"HALF_UP") as log2, round(toFloat(csv.padj_deseq2),3,"HALF_UP") as padj, csv.up_or_down as up
CREATE (:Expression:Primary {name: gene, event_no: event, dendrogram_height: height, samples: sp, median_exp: me, no_of_samples: no_s, leaf_status: leaf, patients: pts, no_of_unique_patients: no_pt, log2fc: log2, padj_deseq2: padj, up_or_down: up});
',
{batchSize:10000,parallel:true,params:{url:fileURL}}) YIELD batches, total
RETURN batches, total;

I get an error saying:


Procedure call provides too many arguments: got 4 expected no more than 3.

Procedure apoc.periodic.iterate has signature: apoc.periodic.iterate(cypherIterate :: STRING?, cypherAction :: STRING?, config :: MAP?) :: batches :: INTEGER?, total :: INTEGER?, timeTaken :: INTEGER?, committedOperations :: INTEGER?, failedOperations :: INTEGER?, failedBatches :: INTEGER?, retries :: INTEGER?, errorMessages :: MAP?, batch :: MAP?, operations :: MAP?, wasTerminated :: BOOLEAN?, failedParams :: MAP?, updateStatistics :: MAP?
meaning that it expects at least 3 arguments of types STRING?, STRING?, MAP?
Description: Runs the second statement for each item returned by the first statement.
This procedure returns the number of batches and the total number of processed rows. (line 4, column 1 (offset: 90))
"CALL apoc.periodic.iterate("
 ^

The only difference is the split function in split(csv.patients,',') than csv.patients in the second query chunk.

How to resolve this? Thanks.


Solution

  • in the split, the single quotes around the coma are messing up with opening and closing the 3 strings for periodic iterate

    use double quotes and you should be good...