cancel
Showing results for 
Search instead for 
Did you mean: 

Head's Up! These forums are read-only. All users and content have migrated. Please join us at community.neo4j.com.

End where statements

skirwan
Node Link

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)
8 REPLIES 8

ameyasoft
Graph Maven

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.

skirwan
Node Link

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,
2X_a_ac9f1ac26581994873d60de93017f58eb74b3163.png

Many Thanks,
Sam

Between ELSE and END you need to insert an empty array:

... ELSE [] END ...

Do this in every occurence in your statement.

skirwan
Node Link

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

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.

skirwan
Node Link

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

In this case you'd use

FOREACH
(x IN SPLIT(line.`Contact Phone`, ',') |
MERGE (p:Phone{Phone:x})
MERGE (c)-[:Owns]->(p)
)

@stefan.armbruster

Thanks for your help on both topics, that cypher query works really well, and that is a very good explanation.

Many thanks,
Sam