我正在尝试编写一个 Cypher 语句,它根据给定的项目标签名称列表来管理标签节点的创建和关系。
调用参数示例:
{
itemId: "foo",
tagNames: ["Tag1", "Tag2", "Tag3"]
}
这是 Cypher 声明:
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
标签节点创建和分配工作一切正常!
我的问题在于
RETURN i
语句,如果我的 $tagNames
列表为空([]
)。在这种情况下,该语句返回 NULL 而不是 i
,但我需要它始终返回 i
。
我还尝试了此处建议的“FOREACH-Trick”:https://stackoverflow.com/a/27578798/5106474
FOREACH(ignoreMe IN CASE WHEN tag IS NOT NULL THEN [1] ELSE [] END |
MERGE (i)-[:hasTag]->(tag)
)
但仍然是同样的行为。
预先感谢您的任何建议!
当
RETURN tag
为空时,$tagNames
将基数减少到零。要解决此问题,请将 CALL
包裹在另一个 CALL
中以保留第一个 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