Conditionally create or merge a node

I am trying to create/merge a node conditionally based on whether a variable does not equal the string 'Title'. I think I have 1 conditional node create working for when a variable value equals the string 'Title' but its hard to test without both working.

not working:
FOREACH(_ IN CASE WHEN regionCoordinatorTitle <> 'Title' THEN [1] ELSE [] END | MERGE (rc:RegionCoordinator {regionCoordinatorTitle: regionalCoordinatorTitle) )
maybe working:
FOREACH(_ IN CASE WHEN regionCoordinatorTitle = 'TITLE' THEN [1] ELSE [] END | CREATE (rc:RegionCoordinator {regionCoordinatorTitle: regionalCoordinatorTitle) )

Hi,

Could you please explain your requirement?

Try this:

FOREACH(ignoreMe IN CASE WHEN regionCoordinatorTitle <> 'Title' THEN [1] ELSE [] END|

MERGE (rc:RegionCoordinator {regionCoordinatorTitle: regionalCoordinatorTitle)

)


FOREACH(ignoreMe IN CASE WHEN regionCoordinatorTitle = 'Title' THEN [1] ELSE [] END|

CREATE (rc:RegionCoordinator {regionCoordinatorTitle: regionalCoordinatorTitle)

)

Sure - I'm using neo4j to create a visual map for a non technical user who wants a visualization of different types of contacts based on regions and office types. They have sent a CSV file of the data. There is currently a lot of dummy data within that file. Instead of omitting that data (ex. Title, Name, Email vs Developer, John Smith, jsmith@email.com) I would like to conditionally create nodes for the dummy data and merge nodes for the actual data.

for reference I found this stackoverflow post with the conditinal merge/create hack

You mean Title is good data and TITLE is dummy data. I thought it was a typo.

Replace 'Title' in the second FOREACH with 'TITLE' .

@pjr4lph,

sorry to say however I am still unable to understand what does it mean by saying Merge /Create . I saw the link you have shared in the post, same link refer to a blog by Mark Needham. Neo4j: LOAD CSV - Handling empty columns | Mark Needham
I hope this link is rather beneficial

@intouch_vivek right, i also saw Mark Needham's post, to use his code as an example:

load csv with headers from "file:/tmp/foo.csv" as row
MERGE (p:Person {a: row.a})
FOREACH(ignoreMe IN CASE WHEN trim(row.b) <> "" THEN [1] ELSE [] END | SET p.b = row.b)
FOREACH(ignoreMe IN CASE WHEN trim(row.c) <> "" THEN [1] ELSE [] END | SET p.c = row.c)
RETURN p

where Mark conditionally SET p.b = row.b or conditionally SET p.c = row.c I would like to conditionally MERGE (node) or conditionally CREATE (node)

@ameyasoft oh wow! that was definitely a typo thank u for catching but unfortunately, i still get the same error when I fix the typo and try your code example. The dummy data is Title and the good data is any string that isn't Title.

@pjr4lph

Where the variable value regionCoordinatorTitle is coming from. As in the blog it is coming from row.column_value

FOREACH(ignoreMe IN CASE WHEN regionCoordinatorTitle <> 'Title' THEN [1] ELSE END|
MERGE (rc:RegionCoordinator {regionCoordinatorTitle: regionalCoordinatorTitle)
)
FOREACH(ignoreMe IN CASE WHEN regionCoordinatorTitle = 'Title' THEN [1] ELSE END|
CREATE (rc:RegionCoordinator {regionCoordinatorTitle: regionalCoordinatorTitle)

LOAD CSV WITH HEADERS FROM 'file:///v2/v2.csv' AS row
WITH row.Region AS region, row.Regional_Coordinator_Title AS regionalCoordinatorTitle,

FOREACH(ignoreMe IN CASE WHEN regionCoordinatorTitle <> 'Title' THEN [1] ELSE [] END |
MERGE (rc:RegionCoordinator {regionCoordinatorTitle: regionalCoordinatorTitle))

FOREACH(ignoreMe IN CASE WHEN regionCoordinatorTitle = 'Title' THEN [1] ELSE [] END |
CREATE (rc:RegionCoordinator {regionCoordinatorTitle: regionalCoordinatorTitle))

MATCH (r:Region {region: region})
MERGE (r)-[:regionCoordinator]->(rc)
RETURN rc

Please try below
LOAD CSV WITH HEADERS FROM 'file:///v2/v2.csv' AS row
FOREACH(ignoreMe IN CASE WHEN row.regionCoordinatorTitle <> 'Title' THEN [1] ELSE END |
MERGE (rc:RegionCoordinator {regionCoordinatorTitle: row.regionalCoordinatorTitle))

FOREACH(ignoreMe IN CASE WHEN row.regionCoordinatorTitle = 'Title' THEN [1] ELSE END |
CREATE (rc:RegionCoordinator {regionCoordinatorTitle: row.regionalCoordinatorTitle))

MATCH (r:Region {region: row.region})
MERGE (r)-[:regionCoordinator]->(rc)
RETURN rc

hhmmm still getting the same error

Invalid input '|': expected whitespace, comment, '{', node labels, MapLiteral, a parameter, a relationship pattern, '(', '.', '[', "=~", IN, STARTS, ENDS, CONTAINS, IS, '^', '*', '/', '%', '+', '-', '=', '~', "<>", "!=", '<', '>', "<=", ">=", AND, XOR, OR or END (line 2, column 88 (offset: 141))
"FOREACH(ignoreMe IN CASE WHEN row.regionCoordinatorTitle <> 'Title' THEN [1] ELSE  END |"

I guess while copy-paste square bracket post else got omit
It should be as below

oh yes corrected, now getting the error:

Invalid input ')': expected an identifier character, '.', whitespace, '(', node labels, '[', "=~", IN, STARTS, ENDS, CONTAINS, IS, '^', '*', '/', '%', '+', '-', '=', '~', "<>", "!=", '<', '>', "<=", ">=", AND, XOR, OR, ',' or '}' (line 3, column 82 (offset: 226))
"MERGE (rc:RegionCoordinator {regionCoordinatorTitle: row.regionalCoordinatorTitle))"

use curly braces

ok! no more errors. the issue now is that the nodes and relationships are being created but they are blank. it seems that lines 2-6 are being ignored because the nodes that are appearing do not have any values or types.

LOAD CSV WITH HEADERS FROM 'file:///v2/v2.csv' AS row
WITH row.Region AS region, row.Regional_Coordinator_Title AS regionalCoordinatorTitle

MATCH (r:Region {region: region})
with region, regionalCoordinatorTitle, r


FOREACH(ignoreMe IN CASE WHEN regionCoordinatorTitle <> 'Title' THEN [1] ELSE [] END |
MERGE (rc:RegionCoordinator {regionCoordinatorTitle: regionalCoordinatorTitle)
MERGE (r)-[:regionCoordinator]->(rc)

)

FOREACH(ignoreMe IN CASE WHEN regionCoordinatorTitle = 'Title' THEN [1] ELSE [] END |
CREATE (rc:RegionCoordinator {regionCoordinatorTitle: regionalCoordinatorTitle)
MERGE (r)-[:regionCoordinator]->(rc)
)

with r

RETURN r

Whatever is created within FOREACH cannot be carried further and hence you need to create the relationship within the FOREACH.

Regarding the code by Mark Needham, I just did not know how this part works:

trim(row.b) <> ""

and <> is just the inequality operator.