Monica Heddneck
Monica Heddneck

Reputation: 3125

creating relationships when using READ CSV in Cypher

I have a really simple CSV that I created so I can practice loading CSVs into Neo4j.

The CSV looks like this:

boxer_id    name      boxer_country total_wins  bdate   fought  fight_id    fight_location  outcome
1         Glass Joe   France            0       1/2/80    2      100          Las Vegas      L
2        Bald Bull    Turkey            2       2/3/81    1      100          Macao          W
3       Soda Popinski Russia            6       3/4/82    4      101          Atlantic City  L
4          Sandman    USA               9       4/5/83    3      101         Japan           W  

I want to make 2 nodes, boxer and fight.

But I'm having trouble connecting the boxers to the fights.

Here's as far as I got:

enter image description here

As you can see, I successfully read in the nodes, but I don't know how to create the relationship between boxers and their boxing matches.

I want to do something like:

CREATE (boxer)-[:AGAINST]->(boxer)  

but this doesn't make sense. I need to use the field fought, which encapsulates the information regarding who has faced who in the ring.

Any advice would be greatly appreciated. I'm not sure how to do this in the context of READ CSV.

Here's my code:

// The goal here is to create a node called Boxer, and pull in properties.

LOAD CSV WITH HEADERS FROM
'file:///test.csv' AS line
WITH line, SPLIT(line.bdate, '/') AS bdate
CREATE (b:boxer  {boxer_id: line.boxer_id})
SET b.byear= TOINT(bdate[2]),
    b.bmonth= TOINT(bdate[0]),
    b.bday = TOINT(bdate[1]),
    b.name = line.name,
    b.country = line.boxer_country,
    b.total_wins = TOINT(line.total_wins)


// Now we make a node called Fight
LOAD CSV WITH HEADERS FROM
'file:///test.csv' AS line
CREATE (f:fight  {fight_id: line.fight_id, fight_loc: line.fight_location})

// Now we set relationships
// ????

Upvotes: 1

Views: 195

Answers (2)

Dave Bennett
Dave Bennett

Reputation: 11216

You could add a few lines to match the boxers you already created and create relationships between them and the newly created fight. I am thinking something along these lines might work for you...

LOAD CSV WITH HEADERS FROM
'file:///test.csv' AS line
MATCH (b1:boxer {boxer_id: line.boxer_id})
WITH line, b1
MATCH (b2:boxer {boxer_id: line.fought})
MERGE (f:fight  {fight_id: line.fight_id})
CREATE (b1)-[:AGAINST]->(b2)
CREATE (b1)-[:FOUGHT_IN]->(f)
CREATE (b2)-[:FOUGHT_IN]->(f)

Upvotes: 1

William Lyon
William Lyon

Reputation: 8546

One option is to just model fights as relationships between Boxer nodes, instead of creating the Fight nodes:

LOAD CSV WITH HEADERS FROM 'file:///test.csv' AS line
MERGE (b1:Boxer {boxer_id: line.boxer_id})
MERGE (b2:Boxer {boxer_id: line.fought})
CREATE (b1)-[f:fought]->(b2)
SET f.location = line.fight_location,
    f.outcome = line.outcome

However it probably makes more sense to model the fights as nodes, since they are events. In that case something like this:

LOAD CSV WITH HEADERS FROM 'file:///text.csv' AS line
MATCH (b:Boxer {boxer_id: line.boxer_id})
MERGE (f:fight  {fight_id: line.fight_id})
ON CREATE SET f.location = line.fight_location
CREATE (b)-[r:FOUGHT_IN]->(f)
WITH r, CASE line.outcome WHEN "W" THEN [1] ELSE [] END AS win
FOREACH (x IN win | SET r.winner = TRUE)

Note here that we are storing the outcome of the fight as a property on the :FOUGHT_IN relationship.

Edit Updated to use MERGE to avoid creating duplicate Fight nodes. When using MERGE you should also create a uniqueness constraint: CREATE CONSTRAINT ON (f:Fight) ASSERT f.fight_id IS UNIQUE; before running the import script.

Upvotes: 0

Related Questions