0

Is there any way to combine these statements into one in Cypher? Another way to ask this is what is the scope of a with statement, when does it end?

I am trying to do a conditional creation of link types from a csv file.

LOAD CSV WITH HEADERS FROM "file:///g:/crs2/DataFlowDB/links.csv" AS row
WITH row WHERE row.type = 'in'
MATCH (start:Actor { key:toInteger(row.from) })
MATCH (end:Actor { key:toInteger(row.to) })
CREATE (start)-[:IN { direction: [row.type]}]->(end)

LOAD CSV WITH HEADERS FROM "file:///g:/crs2/DataFlowDB/links.csv" AS row
WITH row WHERE row.type = 'out'
MATCH (start:Actor { key:toInteger(row.from) })
MATCH (end:Actor { key:toInteger(row.to) })
CREATE (start)-[:OUT { direction: [row.type]}]->(end)
Dr.YSG
  • 7,171
  • 22
  • 81
  • 139

2 Answers2

2

The scope of a WITH extends until the next WITH or you reach a RETURN. In your example, you're getting an error because row is already in scope when you try to alias the results of the second CSV import.

One way around this is to remove row from scope in a WITH clause just before the second CSV import, like this, but with whatever placeholder alias you want.

WITH DISTINCT 1 as ignored

DISTINCT is needed because otherwise you'll still have the same number of rows as before the WITH, with a 1 on each row. This resets you back to a single row.

Then you can freely call the import.

That said, there is a way to handle all processing in a single pass by using APOC procedures to create the relationship with a dynamic type.

LOAD CSV WITH HEADERS FROM "file:///g:/crs2/DataFlowDB/links.csv" AS row
WITH row, upper(row.type) as reltype
MATCH (start:Actor { key:toInteger(row.from) })
MATCH (end:Actor { key:toInteger(row.to) })
CALL apoc.create.relationship(start, reltype, {direction:row.type}, end) YIELD relationship
RETURN relationship

You can of course return whatever you want, but you need to return something, as you cannot end a query with a CALL statement.

InverseFalcon
  • 29,576
  • 4
  • 38
  • 51
  • I tried the APOC approach first, but I ran into some sort of instal, config issue: http://stackoverflow.com/questions/42286508/neo4j-apoc-install-but-missing-procedures – Dr.YSG Feb 17 '17 at 21:27
0

You need foreach:

LOAD CSV WITH HEADERS FROM "file:///g:/crs2/DataFlowDB/links.csv" AS row
FOREACH(t in CASE WHEN row.type = 'in' THEN [1] ELSE [] |
    MATCH (start:Actor { key:toInteger(row.from) })
    MATCH (end:Actor { key:toInteger(row.to) })
    CREATE (start)-[:IN { direction: [row.type]}]->(end)
)
FOREACH(t in CASE WHEN row.type = 'out' THEN [1] ELSE [] |
    MATCH (start:Actor { key:toInteger(row.from) })
    MATCH (end:Actor { key:toInteger(row.to) })
    CREATE (start)-[:OUT { direction: [row.type]}]->(end)
)
stdob--
  • 28,222
  • 5
  • 58
  • 73