我有一个用于创建 Node 的电子邮件地址列表。但是,如果这些电子邮件地址之一已经存在,我不想收到 CATCH '.... Node 已存在' 错误,因为这会终止整个查询,并且不会创建任何 Node 。因此,我在创建 Node 之前使用 MERGE then ON CREATE 检查电子邮件地址是否存在。问题是我需要与第二个 Node 创建关系,因此在合并和创建后我必须使用WITH....CREATE来创建关系,这就是问题...WITH不在“范围内” ' 的 ON CREATE 因此 CREATE (a)--[r]->(b) 现在尝试使用我在上面的 MERGE 中跳过的电子邮件地址创建 a Node ...导致 CATCH '...已经存在...' 错误使我的查询变得垃圾。这是我的密码:
commons.session
.run['tom@abc.com', 'tony@mymail.com',michael@gmail.com'] AS coll
UNWIND coll AS invitee
WITH DISTINCT invitee
MERGE (i {email: invitee})
ON CREATE
SET i:Invitee
WITH i,invitee
CREATE (s:Person {email: 'xyz123@abc.com})-[r:INVITED]->(i)
RETURN i.email AS emails, COUNT(r) AS invitees)
我期望返回的是仅包含创建 Node 和关系的电子邮件地址的列表。基本上我需要处于 ON CREATE 的“范围”内,因为重复项将被跳过。任何有助于完成这项工作的帮助将不胜感激。
最佳答案
[更新2]
WITH [
{email:'tom@abc.com', name:'tom'},
{email:'tony@mymail.com', name:'tony'},
{email:'michael@gmail.com', name:'mike'}] AS coll
MATCH (s:Person {email: 'me@aol.com'})
OPTIONAL MATCH (s)-[x:INVITED]->()
WITH s, coll, COUNT(x) AS orig_count
UNWIND coll AS invitee
WITH DISTINCT s, orig_count, invitee
OPTIONAL MATCH (i {email: invitee.email, name: invitee.name})
FOREACH(ignored IN CASE WHEN i IS NULL THEN [1] ELSE [] END |
CREATE (s)-[r:INVITED]->(:Invitee {email: invitee.email, name: invitee.name})
)
WITH s, orig_count
OPTIONAL MATCH (s)-[x:INVITED]->()
RETURN COUNT(DISTINCT x) - orig_count AS new_relationship_count
说明:
- 如果未找到 Node 模式,
OPTIONAL MATCH
子句将为i
生成一个NULL
值。 CASE WHEN i IS NULL THEN [1] ELSE [] END
当且仅当i
为NULL
时才会返回非空列表>.- 如果列表为空,则
FOREACH
子句将不会执行其包含的写入子句。否则,它将执行所有这些。 - 一开始,此查询首先获取从
s
发出的INVITED
关系的原始数量的计数 (orig_count
)。< - 最后,它会获得最终计数,并从中减去
orig_count
以获得new_relationship_count
。
关于javascript - 在 Neo4j 中创建 Node 时如何跳过重复 Node ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53218420/