I am trying to write a Cypher statement, which manages the creation and relationships of tag nodes according to a given list of tag names for an item.
Example calling parameters:
{
itemId: "foo",
tagNames: ["Tag1", "Tag2", "Tag3"]
}
This is the Cypher statement:
MATCH (i:Item {id: $itemId})
OPTIONAL MATCH (i)-[previousRelations:hasTag]->(:Tag)
DELETE previousRelations
WITH *
CALL {
UNWIND $tagNames as tagName
MERGE (tag:Tag {name: tagName})
ON CREATE SET tag.id = randomUUID(), tag.createdAt = datetime()
RETURN tag
}
MERGE (i)-[:hasTag]->(tag)
RETURN i
The tag node creation and assignment works all fine!
My problem lies in the RETURN i
statement if my $tagNames
list is empty ([]
). In this case the statement returns NULL instead of i
but I need it to always return i
.
I also tried the "FOREACH-Trick" as suggested here: https://stackoverflow.com/a/27578798/5106474
FOREACH(ignoreMe IN CASE WHEN tag IS NOT NULL THEN [1] ELSE [] END |
MERGE (i)-[:hasTag]->(tag)
)
But still, same behaviour.
Thanks in advance for any suggestions!
That RETURN tag
is reducing the cardinality to zero when $tagNames
is empty. To solve this, wrap the CALL
in another CALL
to preserve the cardinality of the first MATCH:
MATCH (i:Item {id: $itemId})
OPTIONAL MATCH (i)-[previousRelations:hasTag]->(:Tag)
DELETE previousRelations
WITH *
CALL {
WITH i
CALL {
UNWIND $tagNames as tagName
MERGE (tag:Tag {name: tagName})
ON CREATE SET tag.id = randomUUID(), tag.createdAt = datetime()
RETURN tag
}
MERGE (i)-[:hasTag]->(tag)
}
RETURN i