Head's Up! These forums are read-only. All users and content have migrated. Please join us at community.neo4j.com.
05-12-2019 11:18 AM
Hi all,
I am using the below cypher quiry to import data from a CSV file into a neo4j database via the neo4j browser.
Largely this query works well, however I am missing relationships as the where clauses are being carried out throughout the query, for example I have a contact with a null Email cell, but a phone number cell, there is no relationship being created between the contact and its phone number because of the where statemen in line 7. All noded are being created successfully but not all relationships. Has anyone any cypher suggestions.
Thanks for your help,
Sam
Load csv with headers from 'file:///S.K_Meta_Contacts2.csv' as line
With line
Merge (c:Contact{Name:line.`Meta_Contacts Name`})
With line
Match (c:Contact{Name:line.`Meta_Contacts Name`})
Where not line.`Contact Email` is NULL
Merge (e:Email{Email:SPLIT(line.`Contact Email`, ',')})
CREATE unique (c)-[:Owns]->(e)
With line
Match (c:Contact{Name:line.`Meta_Contacts Name`})
Where not line.`Contact Phone` is NULL
Merge (p:Phone{Phone:SPLIT(line.`Contact Phone`, ',')})
CREATE unique (c)-[:Owns]->(p)
With line
Match (c:Contact{Name:line.`Meta_Contacts Name`})
Where not line.`External Operators: External Organisations` is NULL
Merge (o:Organization{Name:tostring(line.`External Operators: External Organisations`)})
CREATE unique (c)-[:Works_For]->(o)
With line
Match (c:Contact{Name:line.`Meta_Contacts Name`})
Where not line.`Contact Owner` is NULL
Merge (m:Employee{Name:tostring(line.`Contact Owner`)})
CREATE unique (m)-[:Owner]->(c)
05-12-2019 02:15 PM
Try this:
Load csv with headers from 'file:///S.K_Meta_Contacts2.csv' as line
With line
Merge (c:Contact{Name:line.Meta_Contacts Name
})
FOREACH(ignoreMe IN CASE WHEN line.Contact Email
IS NOT NULL THEN [1] ELSE END |
Merge (e:Email{Email:SPLIT(line.Contact Email
, ',')})
MERGE (c)-[:Owns]->(e)
)
FOREACH(ignoreMe IN CASE WHEN line.Contact Phone
IS NOT NULL THEN [1] ELSE END |
Merge (p:Phone{Phone:SPLIT(line.Contact Phone
, ',')})
MERGE (c)-[:Owns]->(p)
)
FOREACH(ignoreMe IN CASE WHEN line.External Operators: External Organisations
IS NOT NULL THEN [1] ELSE END |
Merge (o:Organization{Name:tostring(line.External Operators: External Organisations
)})
MERGE (c)-[:Works_For]->(o)
)
FOREACH(ignoreMe IN CASE WHEN line.Contact Owner
IS NOT NULL THEN [1] ELSE END |
Merge (m:Employee{Name:tostring(line.Contact Owner
)})
MERGE (m)-[:Owner]->(c)
)
Use MERGE in place of CREATE UNIQUE. For some reasons the back tics are not being seen. Please use them as in your post.
05-13-2019 01:06 AM
Hi @ameyasoft,
Thanks for your suggestion.
This is the query I ran
Load csv with headers from 'file:///S.K_Meta_Contacts2.csv' as line
With line
Merge (c:Contact{Name:line.`Meta_Contacts Name`})
FOREACH(ignoreMe IN CASE WHEN line.`Contact Email` IS NOT NULL THEN [1] ELSE END |
Merge (e:Email{Email:SPLIT(line.`Contact Email`, ',')})
MERGE (c)-[:Owns]->(e)
)
FOREACH(ignoreMe IN CASE WHEN line.`Contact Phone` IS NOT NULL THEN [1] ELSE END |
Merge (p:Phone{Phone:SPLIT(line.`Contact Phone`, ',')})
MERGE (c)-[:Owns]->(p)
)
FOREACH(ignoreMe IN CASE WHEN line.`External Operators: External Organisations` IS NOT NULL THEN [1] ELSE END |
Merge (o:Organization{Name:tostring(line.`External Operators: External Organisations`)})
MERGE (c)-[:Works_For]->(o)
)
FOREACH(ignoreMe IN CASE WHEN line.`Contact Owner` IS NOT NULL THEN [1] ELSE END |
Merge (m:Employee{Name:tostring(line.`Contact Owner`)})
MERGE (m)-[:Owner]->(c)
)
However I get the following error, have you any suggestions as to how to fix this,
Many Thanks,
Sam
05-13-2019 06:24 AM
Between ELSE
and END
you need to insert an empty array:
... ELSE [] END ...
Do this in every occurence in your statement.
05-13-2019 06:44 AM
Hi, @stefan.armbruster
thanks for the help the query runs perfect now. could you briefly explain to me what is happening in the first line of the FOREACH statements.
Regards,
Sam
05-13-2019 09:02 AM
Cypher does not have a real if/then/else statement - since it's not a full programming language. The "trick" is use case when
to construct a single element array or an empty array based on a conditional. That array is then processed using foreach
. See https://markhneedham.com/blog/2014/06/17/neo4j-load-csv-handling-conditionals/ for a more verbose writeup.
05-13-2019 07:23 AM
Also I would appreciate anyones advice on the below matter.
FOREACH
(ignoreMe IN CASE WHEN line.`Contact Phone` IS NOT NULL THEN [1] ELSE [] END |
MERGE (p:Phone{Phone:SPLIT(line.`Contact Phone`, ',')})
MERGE (c)-[:Owns]->(p)
)
The :Phone nodes are not getting split by commas like a hoped they would, the nodes are appearing as 086 123456 789, 086 987654 321 instead of 2 separate nodes each representing a number like I had hoped they would.
many thanks,
sam
05-13-2019 09:04 AM
In this case you'd use
FOREACH
(x IN SPLIT(line.`Contact Phone`, ',') |
MERGE (p:Phone{Phone:x})
MERGE (c)-[:Owns]->(p)
)
05-13-2019 09:27 AM
Thanks for your help on both topics, that cypher query works really well, and that is a very good explanation.
Many thanks,
Sam
All the sessions of the conference are now available online