Relationship that connect the same node in Neo4j - csv

I will try to be very succinct with my problem. I have the node Person that I loaded using a .csv file and I have another .csv file to be loaded - person_speaks_language_0.csv
(got this header: idPerson|languagePSL )
How can I relate this? How can I create this relationship?
Grabbing another example, that is very similar to the previous one, and that I can't solve. I have the Comment node loaded in Neo4j an I need to load another .csv file, that file is - comment_replyOf_comment_0.csv
(got his header: idComment|idComment)
How can I load this file? How can I connect a relation that goes "in and out" from the same node - that connects the same node?

For the first example. there is 2 options.
If you want Language to be a separate node, try this cypher:
LOAD CSV FROM 'person_speaks_language_0.csv' AS line
MATCH (p:Person)
WHERE p.id=line[0]
MERGE (p)-[r:Speaks]->(l:Language { name: line[1])})
RETURN p, l, r
Or, probably, better option
LOAD CSV FROM 'person_speaks_language_0.csv' AS line
MERGE (p:Person { id:line[0] })-[r:Speaks]->(l:Language { name: line[1]) })
RETURN p, l, r
If you want Language to be a property, try this:
LOAD CSV FROM 'person_speaks_language_0.csv' AS line
MERGE (p { id:line[0], language:line[1] })
RETURN p
The RETURN statement is optional and you don't want to include it for a big csv files (although it could be useful for debug).
For the second example, try this:
LOAD CSV FROM 'comment_replyOf_comment_0.csv' AS line
MERGE (c1:Comment { id:line[0] })-[r:Commented]->(c2:Comment { id:line[1]) })
RETURN c1, r, c2

Related

Create nodes from CSV in Neo4j

I have a csv file and I want to make 2 nodes with relation (node country-reported_on->node report_date). I have tried this code but it returns empty nodes with numbers instead of country name.
Here is what my dataset looks like:
PEOPLE_POSITIVE_CASES_COUNT;REPORT_DATE;COUNTRY_SHORT_NAME;PEOPLE_DEATH_COUNT;LIFE_EXPECTANCY;GDP;DENSITY_POPULATION;WORKFORCE
0;22.01.2020;Lesotho;0;54.836;875.353432963926;70.5616600790514
134;09.07.2020;Lesotho;1;54.836;875.353432963926;70.5616600790514
79557;02.03.2021;Zambia;1104;64.194;985.132436038869;94.4781600309238
106470;02.03.2021;Kenya;1863;66.991;1878.58070251348;94.4781600309238
Here is the code that I used:
LOAD CSV WITH HEADERS FROM "file:///dataset.csv"
as row WITH row WHERE row.COUNTRY_SHORT_NAME IS NOT NULL
MERGE (c:Country {name: row.COUNTRY_SHORT_NAME,
life_exp: row.LIFE_EXPECTANCY,
gdp: row.GDP,
density_population: row.DENSITY_POPULATION,
worforce: row.WORKFORCE } )
MERGE ( d:Report_date { date: row.REPORT_DATE } )
MERGE (c)-[:reported_on {cases_count: row.PEOPLE_POSITIVE_CASES_COUNT,
death_count: row.PEOPLE_DEATH_COUNT}]->(d)
EDIT
I changed the delimiter to ';' because that is what we had in our dataset however we still get bad results here is how it looks like in neo4j after running this code:
LOAD CSV WITH HEADERS FROM "file:///dataset.csv"
as row FIELDTERMINATOR ';' WITH row WHERE row.COUNTRY_SHORT_NAME IS NOT NULL
MERGE (c:Country {name: row.COUNTRY_SHORT_NAME,
life_exp: row.LIFE_EXPECTANCY,
gdp: row.GDP,
density_population: row.DENSITY_POPULATION,
worforce: row.WORKFORCE } )
MERGE ( d:Report_date { date: row.REPORT_DATE } )
MERGE (c)-[:reported_on {cases_count: row.PEOPLE_POSITIVE_CASES_COUNT,
death_count: row.PEOPLE_DEATH_COUNT}]->(d)
I think you got confused with node caption in Neo4j browser, all nodes get assigned an node id by default and nodes must be showing that. You can change it to country name property by clicking on node label. Screen shot for reference.

Is there a way to import a csv into Neo4j using foreach or unwind?

I am using the following .csv file for Neo4j import. There are 202 rackets. The numbers below racketX are the rating the user has given that racket.
I want to create the relationships among the users and the rating they have given to each racket. This is my current approach:
LOAD CSV WITH HEADERS FROM 'http://spreding.online/racket-recommendation-system/data/formattedFiles/formattedUsers.csv' AS row
WITH row
WHERE row.username IS NOT NULL
MERGE (u:User {
username: row.username,
height_m: toInteger(row.height),
weight_kg: toInteger(row.weight)
})
WITH row, u, range(3, 204) as indexes
MATCH (r:Racket)
UNWIND r as racket
UNWIND indexes as i
MERGE (u)-[:RATES {rating:toInteger(row[i])}]->(racket)
I get a "cannot access a map" error. Can you help me?
I would break down the load into multiple steps.
Load the users.
LOAD CSV WITH HEADERS FROM 'http://spreding.online/racket-recommendation-system/data/formattedFiles/formattedUsers.csv' AS row
WITH row
WHERE row.username IS NOT NULL
MERGE (u:User {
username: row.username,
height_m: toInteger(row.height),
weight_kg: toInteger(row.weight)
})
Load the rackets.
UNWIND RANGE(1,202) as idx
CREATE (:Racket {racketNumber:"racket"+idx})
Load the relationships.
LOAD CSV WITH HEADERS FROM 'http://spreding.online/racket-recommendation-system/data/formattedFiles/formattedUsers.csv' AS row
UNWIND RANGE (1,202) as idx
MATCH (u:User {username:row.username})
MATCH (r:Racket {racketNumber:"racket"+idx})
MERGE (u)-[:RATES {rating:toInteger(row["racket"+idx])}]->(r)

How can I Download to CSV in Neo4j

I've been trying to download a certain data on my graph and it returns this error :
Neo.ClientError.Statement.SyntaxError: Type mismatch: expected List<Node> but was Node (line 2, column 27 (offset: 77))"CALL apoc.export.csv.data(c,[], "contrib.csv",{})"
This is the query I did :
MATCH (c:Contrib) WHERE c.nationality CONTAINS "|" CALL apoc.export.csv.data(c,[], "contrib.csv",{}) YIELD file, source, format, nodes, relationships, properties, time, rows, batchSize, batches, done, data RETURN file, source, format, nodes, relationships, properties, time, rows, batchSize, batches, done, data
What went wrong ? :(
Thanks
The syntax for the function: apoc.export.csv.data is
apoc.export.csv.data(nodes,rels,file,config)
exports given nodes and relationships as csv to the provided file
The nodes is a collection of nodes rather than a node.
OLD: MATCH (c:Contrib) WHERE c.nationality CONTAINS "|"
CALL apoc.export.csv.data(c,[], "contrib.csv",{})
NEW: MATCH (c:Contrib) WHERE c.nationality CONTAINS "|"
WITH collect(c) as contribs
CALL apoc.export.csv.data(contribs, [], "contrib.csv", {})

Multiple LOAD CSV statements in one Cypher query

Trying to import rows and create nodes from different .csv files in one cypher query:
// User nodes
LOAD CSV WITH HEADERS
FROM 'file:///profile.csv' AS profile_line
CREATE (user:User { userId: profile_line.User })
// Project nodes
LOAD CSV WITH HEADERS
FROM 'file:///project.csv' AS project_line
CREATE (project:Project { projectId: project_line.projectId })
// Image nodes
LOAD CSV WITH HEADERS
FROM 'file:///media.csv' AS image_line
CREATE (image:Image { imageId: '<imageId>' })
Throws the following error:
"WITH is required between CREATE and LOAD CSV (line 9, column 1 (offset: 211))
"CREATE (project:Project { projectId: project_line.projectId })"
I am unclear as to how the WITH statement should be constructed.
If you're using the Neo4j Browser, the easiest way to do this is to just separate your statements with semicolons and turn on the 'multi-statement query editor' (which also gives you a nice little progress indicator as each statement is run):
LOAD CSV WITH HEADERS
FROM 'file:///profile.csv' as profile_line
CREATE (user: User { userId: profile_line.User });
LOAD CSV WITH HEADERS
FROM 'file:///project.csv' as project_line
CREATE (project: Project { projectId: project_line.projectId });
LOAD CSV WITH HEADERS
FROM 'file:///media.csv' as image_line
CREATE (image: Image { imageId: image_line.ImageId });
Otherwise, it is still possible to do this. What we want is a WITH statement that will return a single row irrespective of how many nodes the previous CREATE ended up creating, so any aggregation function will do. For example:
LOAD CSV WITH HEADERS
FROM 'file:///profile.csv' as profile_line
CREATE (user: User { userId: profile_line.User })
WITH max(1) as dummy
LOAD CSV WITH HEADERS
FROM 'file:///project.csv' as project_line
CREATE (project: Project { projectId: project_line.projectId })
WITH max(1) as dummy
LOAD CSV WITH HEADERS
FROM 'file:///media.csv' as image_line
CREATE (image: Image { imageId: image_line.ImageId })
Added 9 labels, created 9 nodes, set 9 properties, completed after 17 ms.
Though I think this is super unclear for future-you, and I wouldn't recommend it.

NETLOGO: find all csv files in a directory and read them in

I don't know how many CSV files in my directory area. However, I would like to read in all of them and save them in global variables that are numbered consecutively.
In R, it would look something like this:
datapath = "D:\\example"
files <- dir(datapath)
for (i in 1:length(files)) {
assign(paste("data",i, sep="_"), read.csv(paste(datapath,files[i], sep="\\"), header=FALSE))
}
which gives me several data frames named data_1, data_2, data_3,....
How can I do the same in NETLOGO??? I have my NetLogo model (.nlogo) and my CSV files (.csv) saved in the same folder.
You could always use the R extension.
extensions[r]
Then you could do what ever you want to do with the csv files in R and then get the data back in netlogo or get a list of csv files (that is what the example below does).
r:eval "source(MyFunctionScript.r)"
r:eval "data = getDatafunction()"
let data r:get "data"
The r function would look something like:
getDatafunction <- function(){
datapath = "D:\\example"
files <- dir(datapath)
for (i in 1:length(files)) {
assign(paste("data",i, sep="_"), read.csv(paste(datapath,files[i], sep="\\"), header=FALSE))
}
return(data)
}