neo4j在合并时创建随机空节点

bpsygsoo  于 2022-11-05  发布在  其他
关注(0)|答案(2)|浏览(201)

我试图创建一个新节点,标签为C,关系为a-->cb-->c,但当且仅当整个模式a-->c,b-->c确实存在。ab已经存在(在查询的其余部分之前合并)。
下面的查询是我要编写的查询的一部分,以完成这一任务。
然而,它创建了一个没有属性和标签的随机空节点,并将关系附加到该节点上。这不应该是可能的,也不是我想要的确定性。我如何阻止这种情况发生?

merge (a: A {id: 1})
merge (b: B {id:1})

with *
call {with a, b
     match (a)-[:is_required]->(dummy:C), (a)-[:is_required]->(b)
     with count(*) as cnt
     where cnt = 0
     merge (temp: Temporary {id: 12948125})
     merge (a)-[:is_required]->(temp)
     return temp
}
return *

谢谢

8yoxcaq7

8yoxcaq71#

我认为这里有几个问题:
1.如何在子查询中使用WITH引入的变量有一些限制。本文将帮助解释这些限制https://neo4j.com/developer/kb/conditional-cypher-execution/
1.我想您可能希望WHERE像其他语言中的IF一样引入条件流。(也许FILTER会是比WHERE更好的关键字选择)。在这种情况下,您将过滤掉“cnt”中为0的部分,但不会再引用cnt,所以merge (temp: Temporary {id: 12948125})merge (a)-[:is_required]->(temp)总是被执行。问题是,由于上述在子查询中使用变量的限制,您试图引用的(a)节点并不存在,它不是外部查询中的节点。Neo4j只创建了一个空节点,没有属性或标签,并将其链接到:Temporary节点-这是完全有效的,也是您获得空节点的原因。
此查询应该会产生您想要的结果:

merge (a: A {id: 1})
merge (b: B {id:1})

with *
// Check if a is connected to b or :C (can't use a again otherwise we'd overwrite it)
optional match(x:A {id: 1}) where exists((a)-[:is_required]->(:C)) or exists((a)-[:is_required]->(b))

with *, count(x) as cnt

// use a case to 'fool' foreach into creating the extra :Temporary node required if a is not related to b or :C
foreach ( i in case when cnt = 0 then [1] else [] end |
    merge (temp: Temporary {id: 12948125})
    merge (a)-[:is_required]->(temp)
)

with *
// Fetch the :Temporary node if it was created
optional match (a)-[:is_required]->(t:Temporary)

return *

您可以使用apoc过程来执行条件查询执行(在链接的文章中提到过),您也可以从(a)中寻找一条路径并检查其长度,而不是引入一个新的MATCH和变量x,然后检查相关节点的存在性。

woobm2wo

woobm2wo2#

如果有人遇到同样的问题,答案是Neo4j浏览器显示的是不存在的节点。

相关问题