I want to load a csv, a timeline of ordered events to create a list of nodes but I'm having trouble creating a :Next relationship to link two rows.
LOAD CSV WITH HEADERS FROM "file:////events.csv" AS row
merge (:Event{id:row.id})-[:NEXT]-> ??? (:Event {id:row[+1].id)
I suppose one approach is to have a column in the CSV pointing to the next row id.
The following queries assume the nodes already exist. If you also want to create the nodes as necessary, replace MATCH with MERGE.
Option 1:
You can have each row in the CSV file contain a variable number of node ids for the nodes that need to be connected together in a single chain, in order. In this case, the CSV file should not have a header row.
LOAD CSV FROM "file:///events.csv" AS ids
UNWIND [i IN RANGE(1, SIZE(ids)-1) | {a: ids[i-1], b: ids[i]}] AS pair
MATCH (a:Event {id: pair.a})
MATCH (b:Event {id: pair.b})
MERGE (a)-[:NEXT]->(b)
Option 2:
You can have each row in the CSV file contain just a pair of node ids that need to be connected together, in order. In this case, the CSV file could have a header row, as demonstrated by this example (using a and b as the headers).
LOAD CSV WITH HEADERS FROM "file:///events.csv" AS pair
MATCH (a:Event {id: pair.a})
MATCH (b:Event {id: pair.b})
MERGE (a)-[:NEXT]->(b)
Related
How can I create a relationship from a node to itself? I have one node (p:person) and my csv has 2 columns: name and vice. Each row in my csv represents a person who a ceo and their vp at the time. Now sometimes vp were ceo so I want to show that relationship. Here is what I was trying but no luck. If I do not include the WITH I receive error saying I need it but when I add the * or a property, it says it cannot find row. I'm stuck
:auto USING PERIODIC COMMIT
LOAD CSV WITH HEADERS FROM 'file:///ceo_vp.csv' AS row
CREATE (p:person {name:coalesce(row.name,'UNK')})
MATCH (p:person {name:row.vice })
WITH *
CREATE (p)-[:was_vp_for]->(p)
There is typo on the variable p; You must assign a different variable name for vp. Here is the script;
LOAD CSV WITH HEADERS FROM 'file:///ceo_vp.csv' AS row
MERGE (ceo:person {name:coalesce(row.name,'UNK')})
MERGE (vice:person {name:row.vice })
CREATE (vice)-[:was_vp_for]->(ceo)
Notice that I used merge because as you said, a vp can be a former ceo (and vice versa) so merge is better than create. Merge will ignore the person if it already exists.
In this example, I would like:
The 'name' to be individual nodes
The 'activity' to be individual nodes
The 'class' to be individual nodes
The system to automatically connect the two names to the same class node 'JUNIOR'
I essentially want the system to connect different names to nodes that they share in common.
I will assume your data is stored in a CSV file named foo.csv in the imports folder, and whose contents look like this:
id,name,activity,class
1,AB,Dance,Junior
2,CD,Biking,Junior
If that is true, then here is a sample Cypher statement that uses LOAD CSV to read that file and create the corresponding nodes and relationships (using MERGE to avoid creating duplicates):
LOAD CSV WITH HEADERS FROM 'file:///foo.csv' AS row
MERGE (p:Person {name: row.name, id: row.id})
MERGE (a:Activity {name: row.activity})
MERGE (c:Class {name: row.class})
MERGE (p)-[:PARTICIPATES_IN]->(a)
MERGE (p)-[:IN_SCHOOL_YEAR]->(c)
I have two csv files:
(clean_data_2.csv : Sample Content as under)
(stationdata.csv : Sample Content as under)
From my cypher query, I want that each station is represented as node and relationship is represented as count.
I did something like this:
USING PERIODIC COMMIT
LOAD CSV WITH HEADERS FROM "file:///stationdata.csv" AS line
CREATE (s:station{id:line.station_id,station_name:line.name});
Loading all station data: it creates all the nodes - source and destination columns
LOAD CSV WITH HEADERS FROM "file:///clean_data_2.csv" AS line
MATCH (src:station),(dst:station)
CREATE (src)-[:TO{ count: [line.count]}]->(dst);
The above part runs, but does not give me count in the relationship between nodes.
I am new to Neo4j - graph databases, thanks!
Your second query's MATCH clause does not specify the names of the station nodes for src and dst, so all possible pairs of station nodes would be matched. That would cause the creation of a lot of extra TO relationships with count properties.
Try using this instead of your second query:
LOAD CSV WITH HEADERS FROM "file:///clean_data_2.csv" AS line
MATCH (src:station {name: line.src}), (dst:station {name: line.dst})
CREATE (src)-[:TO {count: TOINTEGER(line.count)}]->(dst);
This query specifies the station names in the MATCH clause, which your query was not doing.
This query also converts the line.count value from a string (which all values produced by LOAD CSV are) into an integer, and assigns it as a scalar value to the count property, as there does not seem a need for it to be an array.
I can load CSV into Neo4j for a specific label (say PERSON) and the nodes are created under the label PERSON.
I also have another CSV to illustrate the relationships between the person and it looks like:
name1, relation, name2
a, LOVE, b
a, HATE, c
I want to create a relationship between these pairs and the relationship thus created should be "LOVE", "HATE", etc, instead of a rigid RELATION as done by the below script:
load csv with headers from "file:///d:/Resources/Neo4j/person-rel.csv" as p
match (a:PERSON) where a.name=p.name1
match (b:PERSON) where b.name=p.name2
merge (a)-[r:REL {relation: p.REL}]->(b)
By doing this, I have a bunch of REL-type relations but not LOVE- and HATE-relations.
In another word, I want the REL in the last line of the script to be dynamically assigned. And then I can query out all the relationship types using Neo4j API.
Is this possible?
You can install the APOC library and then use apoc.merge.relationship
apoc.merge.relationship(startNode, relType, {key:value, ...}, {key:value, ...}, endNode) - merge relationship with dynamic type
load csv with headers from "file:///d:/Resources/Neo4j/person-rel.csv" as p
match (a:PERSON) where a.name=p.name1
match (b:PERSON) where b.name=p.name2
call apoc.merge.relationship(a,p.REL,{},{},b) yield rel
return count(*);
Hello I was trying to import some data in csv file to neo4j in my ubuntu 12.04.
The csv file is a two column data file with no header its format is like:
12ffew3213,232rwe13
12ffew3213,5yur2ru2r
rwerwerw3,432rwe13
rwerwerw3,5yur2ru2r
the thing is the data in row 0 and row 1 is not unique, for example the data may be 3000 lines and only has 100 unique row0 value and 300 unique row1 value.
And I want to build a graph with unique 100 row0 nodes and 300 row1 nodes and 3000 relationships between those nodes(if 12ffew3213,232rwe13 appears twice there are 2 edges).
Since I am new to neo4j and Cypher. After I tried with CREATE and MERGE for a while I still cannot build UNIQUE nodes. I used something like
LOAD CSV FROM 'file:///home/nate/Downloads/file.csv' AS line
MERGE (:A { number: toString(line[0])})-[:LIKES]->(:B { ID: toString(line[1])})
Any ideas??Thanks ahead!
Here's what you do.
LOAD CSV FROM 'file:///home/nate/Downloads/file.csv' AS line
MERGE (n:A {number : line[0]})
WITH line, n
MERGE (m:B {ID : line[1]})
WITH m,n
MERGE (n)-[:LIKES]->(m);
You first create or match the :A node, then create or match the :B node, then create or match the relationship. The WITH clauses collect the results at each point in the sequence to use in the next. To find out more about WITH clauses, read Section 9.5 in the Neo4j Manual.
The same for csv with header. If our header is 'head1','head2' our code will be:
LOAD CSV WITH HEADERS FROM 'file:///home/nate/Downloads/file.csv' AS line
MERGE (n:A {number : line.head1})
WITH line, n
MERGE (m:B {ID : line.head2})
WITH m,n
MERGE (n)-[:LIKES]->(m);