1

I want to migrate a project from a SQL graph database 'emulation' to neo4j, and now I'm stuck. I have a table with 100000+ rows of the form source_id, relationship_type, target_id. Here's the import statement:

LOAD CSV WITH HEADERS FROM
'file:///usr/local/n4jinput/special_semrelations.csv' AS line
WITH line
MATCH (s:SemObject {sem_id: TOINT(line.ool_source_id)})
MATCH (t:SemObject {sem_id: TOINT(line.ool_target_id)})
CREATE (s)-[line.rlt_relation]->(t)

The problem is in the create statement. What is the correct syntax to retrieve [:WHATEVER_IS_IN_THE_CSV]? Since I have a few dozen relationship types, I need to use some kind of variable here... If this is not possible in CYPHER, are there any other ways to do this in an efficient manner?

Christoph P
  • 133
  • 6
  • Thanks for the hint, cybersam, the answer is indeed the same in principle, although the question sounds different at first sight... – Christoph P Mar 25 '16 at 23:52

1 Answers1

1

Relationship types cannot be parameterized or specified dynamically in Cypher. If you have a defined set of relationship types there is a workaround. You can use a CASE statement to compare relationship types, populate an array if the relationship type matches, then iterate through the array(s) creating the correct relationship type:

LOAD CSV WITH HEADERS FROM 'file:///myfile.csv' AS line
MATCH (s:SemObject {sem_id: TOINT(line.ool_source_id)})
MATCH (t:SemObject {sem_id: TOINT(line.ool_target_id)})
WITH s,t, 
  CASE WHEN line.rlt_relation = "MEMBER_OF" THEN [1] ELSE [] END AS member_of,
  CASE WHEN line.rlt_relation = "BELONGS_TO" THEN [1] ELSE [] END AS belongs_to
FOREACH (x IN member_of | CREATE (s)-[:MEMBER_OF]->(t))
FOREACH (x IN belongs_to | CREATE (s)-[:BELONGS_TO]->(t))
William Lyon
  • 8,371
  • 1
  • 17
  • 22
  • Thanks for the reply and the workaround. I'll try that. BTW, is it for technical reasons that relationship types cannot be specified dynamically in Cypher, or is it to enforce a certain kind of workflow or modeling habit? – Christoph P Mar 25 '16 at 21:41
  • I believe the reason has to do with the process of generating the query plan. Each Cypher query is compiled into an execution plan, which is then cached so the next time the query is seen the plan can be reused. However, if the relationship type or node label is parameterized then the query plan cannot be cached (because the execution plan can change with the relationship types / node labels). – William Lyon Mar 26 '16 at 03:27
  • Works like a charm, thank you! – Christoph P Mar 27 '16 at 22:23