【问题标题】:Neo4j Cypher: Create a relationship only if the end node existsNeo4j Cypher:仅当端节点存在时才创建关系
【发布时间】:2017-05-24 18:29:08
【问题描述】:

similar question 为基础,我想要最高效的方式来处理这种情况。

MERGE (n1{id:<uuid>})
SET n1.topicID = <unique_name1>
IF (EXISTS((a:Topic{id:<unique_name1>})) |  CREATE UNIQUE (n1)-[:HAS]->(a))

MERGE (n2{id:<uuid>})
SET n2.topicID = <unique_name2>
IF (EXISTS((a:Topic{id:<unique_name2>})) |  CREATE UNIQUE (n2)-[:HAS]->(a))

很遗憾,IF 不存在,EXISTS 不能用于匹配或查找唯一节点。

  • 我不能使用 OPTIONAL MATCH,因为这样 CREATE UNIQUE 会抛出一个空异常(尽管我希望它会忽略空参数)
  • 我不能使用 MATCH,因为如果主题不存在,我将丢失所有行。
  • 我不能使用 MERGE,因为如果节点还不存在,我不想创建它。
  • 我不能使用 APOC,因为我不能保证它可以在我们的 Neo4j 服务器上使用。

我现在最好的解决方案是

MERGE (a:TEST{id:1})
WITH a
OPTIONAL MATCH (b:TEST{id:2})
// collect b so that there are no nulls, and rows aren't lost when no match
WITH a, collect(b) AS c
FOREACH(n IN c | CREATE UNIQUE (a)-[:HAS]->(n))
RETURN a

但是,这似乎有点复杂,需要 2 个 WITHs 才能实现本质上的 CREATE UNIQUE RELATION if start and end node exist(并且在计划中有一个渴望)。有没有可能做得更好? (使用 Cypher 3.1)

【问题讨论】:

    标签: neo4j cypher


    【解决方案1】:

    你可以简化很多:

    MERGE (a:TEST{id:1})
    WITH a
    MATCH (b:TEST{id:2})
    CREATE UNIQUE (a)-[:HAS]->(b)
    RETURN a;
    

    (单个)WITH 子句用于将查询拆分为 2 个“子查询”。

    因此,如果MATCH 子查询失败,它只会中止自己的子查询(以及任何后续子查询),但不会回滚之前成功的MERGE 子查询。

    但是,请注意,每当最终子查询失败时,RETURN 子句将不会返回任何内容。您必须确定这是否可以接受。

    因为上面的RETURN 子句只会在b 存在的情况下返回一些东西,所以返回b 或路径可能更有意义。这是后者的一个示例(即使路径已经存在,p 也会被赋值):

    MERGE (a:TEST{id:1})
    WITH a
    MATCH (b:TEST{id:2})
    CREATE UNIQUE p=(a)-[:HAS]->(b)
    RETURN p;
    

    [更新]

    在 neo4j 4.0+ 中,CREATE UNIQUE 不再支持,因此需要使用 MERGE 代替。

    另外,如果你想在b不存在的情况下返回a,你可以使用APOC函数apoc.do.when

    MERGE (a:TEST{id:1})
    WITH a
    OPTIONAL MATCH (b:TEST{id:2})
    CALL apoc.do.when(
      b IS NOT NULL,
      'MERGE (a)-[:HAS]->(b)',
      '',
      {a: a, b: b}) YIELD value
    RETURN a;
    

    【讨论】:

    • 有没有办法在子查询失败的情况下返回node-a?
    • 谢谢。但我试过community.neo4j.com/t/how-to-use-if-else-condition-in-neo4j/…。即使子查询失败,它也允许返回 node-a,因为它仅在条件为真时运行。但是非常感谢您的回答。
    • 是的,这是旧的解决方法。添加了 APOC 程序以避免必须使用它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-12
    • 2014-01-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-07-20
    相关资源
    最近更新 更多