Neo4j Cypher - creating nodes and setting labels with LOAD CSV
Asked Answered
S

5

10

I’m trying to use LOAD CSV to create nodes with the labels being set to values from the CSV. Is that possible? I’m trying something like:

LOAD CSV WITH HEADERS FROM 'file:///testfile.csv' AS line
CREATE (x:line.label)

...but I get an invalid syntax error. Is there any way to do this?

Scouring answered 28/7, 2014 at 10:12 Comment(0)
L
9

bicpence,

First off, this is pretty easy to do with a Java batch import application, and they aren't hard to write. See this batch inserter example. You can use opencsv to read your CSV file.

If you would rather stick with Cypher, and if you have a finite set of labels to work with, then you could do something like this:

USING PERIODIC COMMIT 1000
LOAD CSV WITH HEADERS FROM 'file:///testfile.csv' AS LINE
CREATE (n:load {lab:line.label, prop:line.prop});

CREATE INDEX ON :load(lab);

MATCH (n:load {lab:'label1'})
SET n:label1
REMOVE n:load
REMOVE n.lab;

MATCH (n:load {lab:'label2'})
SET n:label2
REMOVE n:load
REMOVE n.lab;

Grace and peace,

Jim

Lomalomas answered 28/7, 2014 at 15:53 Comment(0)
W
3

Unfortunately not, parameterized labels are not supported

Chris

Whitener answered 28/7, 2014 at 10:17 Comment(0)
K
2

you can do a workaround - create all nodes and than filter on them and create the desired nodes, than remove those old nodes

LOAD CSV WITH HEADERS FROM 'file:///testfile.csv' AS line
CREATE (tmp:line[1])
WITH tmp
CREATE (x:Person {name: labels(tmp)[0]})
WITH tmp
REMOVE tmp

paste this into http://console.neo4j.org to see example:

LOAD CSV 
WITH HEADERS FROM "http://docs.neo4j.org/chunked/2.1.2/csv/import/persons.csv" AS csvLine
CREATE (p:tmp { id: toInt(csvLine.id), name: csvLine.name })
WITH p
CREATE (pp:Person { name: labels(p)[0]})
WITH p, pp
DELETE p
RETURN pp
Katheleenkatherin answered 28/7, 2014 at 11:39 Comment(2)
How exactly is this setting the label of the node with data from CSV? For what I understood, all this does is to add a property from the CSV, but not the label itself - all the created nodes have the "Person" label.Crofter
@LucasLima yes, its supposed to create just a property, not the label. at the time of writing this answer, node labeling in neo4j wasnt available (it was introduced in version 2), just the relationship labels. thats why i answered with a workaround as mentioned in the answer. today, of course, you can label the node straightforwardKatheleenkatherin
T
0

I looked around at a few questions like this, and came to the conclusion that a nice concise way to handle these kinds of complex frustrations of not being able to easily add dynamic labels through 'LOAD CSV', is simply use your favorite programming language to read CSV lines, and produce a text output file of Cypher statements that will produce the Neo4j node/edge structure that you want. Then you will also be able to edit the text file directly, to alter whatever you want to further customize your commands.

I personally used Java given I am most comfortable with Java. I read each line of the CSV into a custom object that represents a row in my CSV file. I then printed to a file a line that reflects the Cypher statement I wanted. And then all I had to do was cut and paste those commands into Neo4j browser command line.

This way you can build your commands however you want, and you can completely avoid the limitations of 'LOAD CSV' commands with Cypher

Tailorbird answered 23/7, 2019 at 18:56 Comment(1)
It is indeed easier to generate working queries with code, however creates more memory overhead, more code to maintain and misses out on the features of the db in use - neo4j in this case.Declamation
D
0

Jim Biard's answer works but uses PERIODIC COMMIT which is useful however deprecated.

I was able to write a query that:

  1. Loads from CSV
  2. Uses multiple transactions
  3. Creates nodes
  4. Appends labels
  5. Will work for 4.5 and onwards
:auto LOAD CSV WITH HEADERS FROM 'file:///nodes_build_ont_small.csv' AS row
CALL { 
        with row
        call apoc.create.node([row.label], {id: row.id})
        yield node
        return null
} IN TRANSACTIONS of 100 rows 
return null

Seems that apoc procedures are more useful then the commands themselves since this is not possible (at least in my attempts) with CREATE.

Declamation answered 14/7, 2022 at 12:6 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.