Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Neo4j cypher - Import CSV and add relationships between nodes based on the csv values

Tags:

neo4j

cypher

Is it possible in cypher to create different relationship between nodes based on the value of csv using the import functionality .

Eg : For a given csv data

product_id  user_id  action
1           1        VIEW
1           2        PURCHASE

I need to create product node(product_id) , user node(user_id) and either VIEW or PURCHASE relationship between 'user' and product node based on the value of 'action' field in csv .

Below are the approaches I tried . I know the syntax is incorrect but just to give an idea what I am trying to do .

USING PERIODIC COMMIT
LOAD CSV WITH HEADERS FROM "file://pathto/product-event.csv" AS csvLine 
FIELDTERMINATOR ','
MERGE ( prod:Product{pid: toInt(csvLine.product_id)} )
MERGE ( usr:User { cid: toInt(csvLine.userid)  })
WITH prod,usr , CASE  
    WHEN csvLine.action ='VIEW' THEN  'VIEW'
    WHEN csvLine.action ='PURCHASE' THEN  'PURCHASE'
    ELSE 'VIEW' END AS action
MERGE (usr)-[:action]->(prod)



USING PERIODIC COMMIT
LOAD CSV WITH HEADERS FROM "file:///pathto/product-event.csv" AS csvLine 
FIELDTERMINATOR ','
MERGE ( prod:Product {pid: toInt(csvLine.productid) } )
MERGE ( usr:User { cid: toInt(csvLine.userid) }
    )
ON CREATE SET 
    prod.created=timestamp()
WHERE csvLine.action = 'VIEW'
MERGE (cust)-[:VIEW]->(prod)
WHERE csvLine.action = 'PURCHASE'
MERGE (usr)-[:PURCHASE]->(prod)

There may be simple way to do it . but I am not getting any reference online. Thanks.

like image 677
krishnaraj vr Avatar asked Feb 12 '23 06:02

krishnaraj vr


2 Answers

You cannot have dynamic relationship types. However there is a workaround by populating conditionally an array with 1 or 0 elements and applying FOREACH:

USING PERIODIC COMMIT
LOAD CSV WITH HEADERS FROM "file://pathto/product-event.csv" AS csvLine 
FIELDTERMINATOR ','
MERGE ( prod:Product{pid: toInt(csvLine.product_id)} )
MERGE ( usr:User { cid: toInt(csvLine.userid)  })
FOREACH(ignoreMe IN CASE WHEN csvLine.action='VIEW' THEN [1] ELSE [] END | 
    MERGE (usr)-[:VIEW]->(prod) )
FOREACH(ignoreMe IN CASE WHEN csvLine.action='PURCHASE' THEN [1] ELSE [] END | 
    MERGE (usr)-[:PURCHASE]->(prod) )

See also http://www.markhneedham.com/blog/2014/08/22/neo4j-load-csv-handling-empty-columns.

like image 111
Stefan Armbruster Avatar answered May 03 '23 19:05

Stefan Armbruster


Not exactly what you want, but possibly effective:

USING PERIODIC COMMIT 
LOAD CSV WITH HEADERS FROM "file://pathto/product-event.csv" AS csvLine      
FIELDTERMINATOR ',' 
MERGE ( prod:Product{pid: toInt(csvLine.product_id)} )   
MERGE ( usr:User { cid: toInt(csvLine.userid)  }) 
MERGE (usr)-[:action {type: csvLine.action}]->(prod) )
like image 29
Lighthart Avatar answered May 03 '23 17:05

Lighthart