All the nodes I'll be using have unique constraints associated to them.
I tried to create new nodes like this (I thought about MERGE so it would not create the node if it already exists):
MERGE (n:url{url_addr:'test.com'})-[:FROM_DEVICE]->(o:device{mode:'iphone'})
And the node already exists it returns this error:
Node(21) already exists with label `url` and property `url_addr` = 'test.com'
It was obvious, since I didn't match them beforehand, so I did it in order to just pass the results properties:
MATCH (n:url{url_addr:'test.com'}), (o:device{mode:'iphone'})
MERGE (n)-[:FROM_DEVICE]->(o)
But in case any of this records do not exist new nodes will not be created.
So I thought about using OPTIONAL MATCH, since it would replace any non-existent value with null, but this means it would also replace the properties I passed with null values.
OPTIONAL MATCH (n:url{url_addr:'test.com'}) RETURN n
MERGE n-[:FROM_DEVICE]->(o:device{mode:'iphone'})
It returned this error:
Failed to create relationship ` REL87(d65d30eb-65f5-4460-b166-15996622cf1b)`, node `n` is missing. If you prefer to simply ignore rows where a relationship node is missing, set 'cypher.lenient_create_relationship = true' in neo4j.conf
So I thought about using CASE statements in order to first verify if the match would return null and then create the node to define the relationship, but things didn't work well:
OPTIONAL MATCH (n:url{url_addr:'test.com'})
WITH n as test
RETURN CASE
WHEN test IS NULL THEN CREATE (:url{url_addr:'test.com'})
END
This happens:
Invalid input '{': expected
"!="
"%"
")"
"*"
"+"
","
"-"
"."
"/"
":"
"<"
"<="
"<>"
"="
"=~"
">"
">="
"AND"
"CONTAINS"
"ENDS"
"IN"
"IS"
"OR"
"STARTS"
"XOR"
"["
"^" (line 4, column 51 (offset: 135))
" WHEN CASE IS NULL THEN CREATE (a:cookie_id{url:'test.com'})"
^
Removing the properties of the node does not help.