我有一个用于创建节点的电子邮件地址列表。但是,如果这些电子邮件地址之一已经存在,则我不想收到CATCH'....节点已存在'错误,因为这将杀死整个查询,并且不会创建任何节点。因此,在创建节点之前,我先使用MERGE然后ON CREATE检查电子邮件地址是否存在。问题是我需要与第二个节点创建关系,因此在MERGE和ON CREATE之后,我必须使用WITH .... CREATE来创建关系,这就是问题所在... WITH不在'scope范围内'的ON CREATE,因此CREATE(a)-[r]->(b)现在尝试使用我在上面的MERGE中跳过的电子邮件地址创建一个节点...导致CATCH'...已经存在...”错误地将我的查询删除。这是我的CYPHER:
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)
我希望返回的是仅创建了节点和关系的电子邮件地址的列表。基本上,我需要处于ON CREATE的“作用域”中,因为重复项将被跳过。对此工作的任何帮助将不胜感激。
答案 0 :(得分:1)
[更新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
说明:
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
。答案 1 :(得分:0)
好吧...所以FOREACH和CASE都没有成功。实际上,WHERE子句可以。如问题中所述,我最初的需求是接受电子邮件列表,创建列表中不存在用于电子邮件的节点的节点,并返回已创建电子邮件节点的列表以及数量...。并且没有在“电子邮件已存在...”错误CATCH语句上失败。这是我提出的解决方案:
<IfModule reqtimeout_module>
RequestReadTimeout header=0
RequestReadTimeout body=0
</IfModule>
使用WHERE子句,我可以只关注那些尚未创建节点的电子邮件。
感谢@cybersam对OPTIONAL MATCH的建议以及为可能的解决方案而进行的迭代。