我有一个用于创建节点的电子邮件地址列表。但是,如果其中一个电子邮件地址已经存在,我不希望获得CATCH'....节点已存在'错误,因为这会终止整个查询,并且不会创建任何节点。所以我在创建节点之前使用MERGE然后在创建时检查电子邮件地址是否存在。问题是我需要创建一个与第二个节点的关系所以在MERGE和ON CREATE之后我必须使用WITH .... CREATE来创建关系,这就是问题...... WITH不在'范围内'ON CREATE'所以CREATE(a) - [r] - >(b)现在尝试使用我在上面的MERGE中跳过的电子邮件地址创建一个节点...导致CATCH'...已经存在...'错误我的查询垃圾。这是我的CYPHER:
commons.session
.run['[email protected]', '[email protected]',[email protected]'] 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: '[email protected]})-[r:INVITED]->(i)
RETURN i.email AS emails, COUNT(r) AS invitees)
我期望返回的是仅列出创建节点和关系的电子邮件地址的列表。基本上我需要在ON CREATE的“范围”中,因为重复将被跳过。任何帮助做这项工作将不胜感激。
[更新2]
WITH [
{email:'[email protected]', name:'tom'},
{email:'[email protected]', name:'tony'},
{email:'[email protected]', name:'mike'}] AS coll
MATCH (s:Person {email: '[email protected]'})
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
说明:
OPTIONAL MATCH
子句将为NULL
生成i
值。CASE WHEN i IS NULL THEN [1] ELSE [] END
是i
时,NULL
将返回非空列表。FOREACH
子句不会执行其包含的write子句。否则,它将执行所有这些。orig_count
传出的原始INVITED
关系数的计数(s
)。orig_count
得到new_relationship_count
。好的......所以FOREACH和CASE都没有做到这一点。实际上WHERE子句做了。我在问题中所述的原始需求是接受电子邮件列表,创建节点,其中列表中的电子邮件不存在节点,并返回创建的电子邮件节点的列表以及计数的数量....并没有失败的'电子邮件已经存在...'错误CATCH声明。这是我集合的解决方案:
MATCH(s:Person {email: '[email protected]'})
WITH s, ['[email protected]','[email protected]','[email protected]','[email protected]'] AS coll
UNWIND coll AS invitee
WITH DISTINCT invitee, s
OPTIONAL MATCH (i {email: invitee})
WITH s,invitee, i
WHERE i IS NULL
CREATE (s)-[r:INVITED]->(n:Invitee {email:invitee})
RETURN s,n, COUNT(r)
使用WHERE子句,我只能关注那些没有创建节点的电子邮件。
感谢@cybersam对OPTIONAL MATCH的建议以及他对可能解决方案的迭代。