简体   繁体   English

Neo4j Cypher-条件With子句查询

[英]Neo4j Cypher- Conditional With clause query

I am writing the below Neo4j Cypher query to add new Part and remove old Part from Vehicle node. 我正在编写下面的Neo4j Cypher查询来添加新的Part并从Vehicle节点中删除旧的Part I am using Neo4j (version 3.4.1) 我正在使用Neo4j(版本3.4.1)

newParts and removedParts are my parameters. newPartsremovedParts是我的参数。 They are lists of String . 它们是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))

It works fine when I provide newParts parameter as non-empty. 当我将newParts参数提供为非空时,它工作正常。

However when this is empty, I don't get back my final nodes and relationships. 但是当它为空时,我不会回到我的最终节点和关系。 I do understand why that is happening because unwind stops execution when the list is empty. 我明白为什么会发生这种情况,因为当列表为空时,展开会停止执行。 I tried moving with..unwind part below del and it successfully deletes removedParts Part . 我试着动with..unwind部之下del它成功地删除removedParts Part However it doesn't return final nodes and relationship as they come after unwind. 然而,它不会返回最后的节点和关系,因为它们在放松之后。

I am not sure how to make this work with empty newParts parameter as well. 我不知道如何使用空的newParts参数来完成这项工作。 I was trying to use case but I think case doesn't work with nodes and relationships. 我试图使用case但我认为case不适用于节点和关系。

Any help or pointers would be highly appreciated. 任何帮助或指示将受到高度赞赏。

Thanks in advance 提前致谢

V V

Idea 理念

You could use the conditional cypher execution of the APOC user library in combination with a non-empty check of your parameter newParts . 您可以将APOC用户库条件密码执行与参数newParts的非空检查结合使用。 Please prefer apoc.do.when over apoc.when as it is executed in a read/write context, which is necessary for the MERGE clause. apoc.do.when选择apoc.do.when over apoc.when因为它是在读/写上下文中执行的,这对于MERGE子句是必需的。

Proposed solution 提出的解决方案

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);

Explanation 说明

  • line 2: calling the if-then-else construct of the APOC user library 第2行:调用APOC用户库的if-then-else结构
  • line 3: the to be evaluated condition, in this case the check if the parameter newParts is not empty 第3行:要评估的条件,在这种情况下检查参数newParts是否为空
  • line 5-11: the if section, which hands over the Vehicle r 第5-11行:if部分,交出Vehicle r
  • line 13-17: the else section 第13-17行:其他部分
  • line 18: defining the parameter that have to be provided to the if-then-else construct and retrieving the result from it 第18行:定义必须提供给if-then-else构造的参数并从中检索结果

I was able to come up with an answer for my own question thanks to the advice and suggestion from Neo4j admins on Neo4j slack channel. 由于Neo4j管理员对Neo4j松弛频道的建议和建议,我能够为自己的问题找到答案。

If you want to use plain Cypher query you can use the below answer: 如果您想使用普通的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

Hope somebody finds it helpful! 希望有人觉得它有用!

Regards, V 问候,V

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM