Reputation: 410
Say I have a node in the database with label L and multiple random properties A=B, C=D, etc. I want to merge another node in the database also with label L but only has the properties A=B.
With current Cypher, I could just do a simple:
merge (node:L {A:B}) return node
But since match/merge considers any nodes with those properties count, it will be merged into the first node. Is there any way to get this exact match? I was thinking of doing something like a
merge (node:L {props}) where {props} == {all node's props}
but that functionality to list all the node's props doesn't exist though it's on their top five ideas.
Upvotes: 1
Views: 170
Reputation: 2343
If you know the properties you want to compare this will do the trick.
MATCH (node:L {a: "a"})
WHERE LENGTH(KEYS(node)) = 1
WITH (CASE COUNT(node) WHEN 0 then [1] END) AS X
FOREACH (x in X | create (a:L {a:"a"}));
The number on the LENGTH line must be equal to the number of properties you want to compare, at this case, one.
LENGTH(KEYS(node)) = 1
MATCH (node:L {a: "a"})
WHERE LENGTH(KEYS(node)) = 1
WITH (CASE COUNT(node) WHEN 0 then [1] END) AS X
FOREACH (x in X | create (a:L {a:"a"}))
with X
MATCH (node:L {a: "a"}) return node;
Upvotes: 2
Reputation: 67044
If you know exactly which property names you want to exclude when determining if there are any matches (prior to creating a node), you can do something like the following. In this example, the properties to exclude when determining if there is a match are "C", "D", and "E".
OPTIONAL MATCH (node:L {A: "B"})
WHERE NOT (has(node.C) OR has(node.D) OR has(node.E))
WITH (CASE WHEN node IS NULL THEN [1] ELSE [] END) AS cn
FOREACH (x IN cn | CREATE (:L {A: "B"}))
RETURN cn[0];
The returned value will be 1
if the node was created, or null
if it was not.
Upvotes: 1