cancel
Showing results for 
Search instead for 
Did you mean: 

Conditionally create or merge a node

pjr4lph
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) )

16 REPLIES 16

intouch_vivek
Graph Steward

Hi,

Could you please explain your requirement?

ameyasoft
Graph Maven
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)

)

pjr4lph
Node

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. https://markhneedham.com/blog/2014/08/22/neo4j-load-csv-handling-empty-columns/
I hope this link is rather beneficial

pjr4lph
Node

@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 |"

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

trim(row.b) <> ""

and <> is just the inequality operator.

intouch_vivek
Graph Steward

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

pjr4lph
Node

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

pjr4lph
Node

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.

Nodes 2022
Nodes
NODES 2022, Neo4j Online Education Summit

On November 16 and 17 for 24 hours across all timezones, you’ll learn about best practices for beginners and experts alike.