Reputation: 3125
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:
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
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
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