我正在编写下面的Neo4j Cypher查询,以添加新的Part
并从Part
节点中删除旧的Vehicle
。我正在使用Neo4j(版本3.4.1)
newParts
和removedParts
是我的参数。它们是String
的列表。
with {newParts} AS newParts
unwind newParts as newPart
match (r:Vehicle) where id(r)=639
merge (r)-[:HAS_PART]->(np:Part{name:newPart})
on create np+={lastModifiedDateTime:localdatetime(), createdDateTime:localdatetime()}
with r optional match (r)-[rel:HAS_PART]-(p:Part) where p.name in {removedParts}
delete rel
with r match q=(r)--()
return nodes(q), relationships(q))
当我将newParts参数设置为非空时,效果很好。
但是,当它为空时,我不会取回我的最终节点和关系。我确实知道为什么会这样,因为当列表为空时,展开会停止执行。我尝试将with..unwind
的部分移到del
下方,它成功删除了removeParts Part
。
但是,展开后它们不会返回最终的节点和关系。
我不确定如何使用空的newParts参数来使其工作。我试图使用case
,但我认为case
不适用于节点和关系。
我们将不胜感激任何帮助或指针。
预先感谢
V
答案 0 :(得分:2)
您可以将conditional cypher execution中的APOC user library与参数newParts
的非空检查结合使用。与apoc.do.when
相比,apoc.when
更受欢迎,因为它是在读/写上下文中执行的,这对于MERGE子句是必需的。
WITH $newParts AS newParts, $removedParts AS removedParts
CALL apoc.do.when(
size($newParts) > 0,
// true case
'
UNWIND newParts AS newPart
MATCH (r:Vehicle) WHERE id(r)=639
MERGE (r)-[:HAS_PART]->(np:Part{name:newPart})
ON CREATE np+={lastModifiedDateTime:localdatetime(), createdDateTime:localdatetime()}
RETURN r;
',
// false case
'
UNWIND newParts AS newPart
MATCH (r:Vehicle) WHERE id(r)=639
RETURN r;
',
{newParts: newParts}) YIELD value AS result
WITH DISTINCT result.r AS r, removedParts
OPTIONAL MATCH (r)-[rel:HAS_PART]-(p:Part) WHERE p.name IN removedParts
DELETE rel
WITH DISTINCT r
MATCH q=(r)--()
RETURN nodes(q), relationships(q);
newParts
是否为空Vehicle
r
答案 1 :(得分:1)
在Neo4j闲置频道上,由于Neo4j管理员的建议和建议,我能够提出自己的问题的答案。
如果您想使用普通的Cypher查询,可以使用以下答案:
MATCH (r:Vehicle) WHERE id(r)=639
FOREACH(newPart IN {newParts}|
MERGE (np:Part{id:newPart})
ON CREATE SET np+={partProperties}
MERGE (r)-[:HAS_PART]->(np))
WITH DISTINCT r SET r+={vehicleProperties}
WITH DISTINCT r OPTIONAL MATCH p=(r)-[rel:HAS_PART]-(p:Part) where p.name in {removedParts}
DELETE rel
WITH DISTINCT r
MATCH q=(r)--()
RETURN q
希望有人发现它有帮助!
关于, V