Chuck
Chuck

Reputation: 1293

neo4j: how to import and create many relationships

I got the basics of Neo4j Desktop. This is a production case: we have workflow IDs. When a workflow job finishes, it triggers another job to start. That's the relationship.

I already have 300 WF jobs defined, now I just need to create 800 relationships. I can do one at a time. For example, this works:

MATCH (u) WHERE u.WF_ID = 7 
MATCH (v) WHERE v.WF_ID = 8
CREATE (u)-[:TRIGGERS]->(v) return u,v;

But if I take a whole bunch of commands like the one above, either copy and paste into the browser or import a file, I get errors. I tried like this:

MATCH (u) WHERE u.WF_ID = 8 
MATCH (v) WHERE v.WF_ID = 10 
CREATE (u)-[:TRIGGERS]->(v)

MATCH (u) WHERE u.WF_ID = 11 
MATCH (v) WHERE v.WF_ID = 12 
CREATE (u)-[:TRIGGERS]->(v)

MATCH (u) WHERE u.WF_ID = 11 
MATCH (v) WHERE v.WF_ID = 14 
CREATE (u)-[:TRIGGERS]->(v)

return u,v

And I get:

WITH is required between CREATE and MATCH (line 2, column 1 (offset: 85))
"MATCH (u) WHERE u.WF_ID = 11 MATCH (v) WHERE v.WF_ID = 12 <br>CREATE (u)-[:TRIGGERS]->(v)"

I'm looking at the Cypher documentation on WITH, but it's not helping me to understand what I need for this case.

Thanks for your help!

Upvotes: 0

Views: 44

Answers (1)

stdob--
stdob--

Reputation: 29172

WITH is also used to separate reading from updating of the graph. Every part of a query must be either read-only or write-only. When going from a writing part to a reading part, the switch must be done with a WITH clause.

https://neo4j.com/docs/developer-manual/current/cypher/clauses/with/#with-introduction

So you need to add WITH between the parts (we need an intermediate variable result because otherwise only the last result will return):

MATCH (u) WHERE u.WF_ID = 8 
MATCH (v) WHERE v.WF_ID = 10 
CREATE (u)-[r:TRIGGERS]->(v)
WITH [[u, v, r]] AS result

MATCH (u) WHERE u.WF_ID = 11 
MATCH (v) WHERE v.WF_ID = 12 
CREATE (u)-[r:TRIGGERS]->(v)
WITH result + [[u, v, r]] AS result

MATCH (u) WHERE u.WF_ID = 11 
MATCH (v) WHERE v.WF_ID = 14 
CREATE (u)-[r:TRIGGERS]->(v)
WITH result + [[u, v, r]] AS result

RETURN result

But this variant of the query is ugly. Since the result of each part is not used in the next, we can use the UNION:

MATCH (u) WHERE u.WF_ID = 8 
MATCH (v) WHERE v.WF_ID = 10 
CREATE (u)-[r:TRIGGERS]->(v)
RETURN u, v, r

UNION

MATCH (u) WHERE u.WF_ID = 11 
MATCH (v) WHERE v.WF_ID = 12 
CREATE (u)-[r:TRIGGERS]->(v)
RETURN u, v, r

UNION

MATCH (u) WHERE u.WF_ID = 11 
MATCH (v) WHERE v.WF_ID = 14 
CREATE (u)-[r:TRIGGERS]->(v)
RETURN u, v, r

Or we can make the query even more compact by using the UNWIND:

WITH [[8, 10], [11, 12], [11, 14]] AS pids

UNWIND pids AS ids

    MATCH (u) WHERE u.WF_ID = ids[0] 
    MATCH (v) WHERE v.WF_ID = ids[1]
    CREATE (u)-[r:TRIGGERS]->(v)

RETURN u, v, r

Upvotes: 1

Related Questions