如何在Neo4j中创建节点时跳过重复节点
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何在Neo4j中创建节点时跳过重复节点相关的知识,希望对你有一定的参考价值。
我有一个用于创建节点的电子邮件地址列表。但是,如果其中一个电子邮件地址已经存在,我不希望获得CATCH'....节点已存在'错误,因为这会终止整个查询,并且不会创建任何节点。所以我在创建节点之前使用MERGE然后在创建时检查电子邮件地址是否存在。问题是我需要创建一个与第二个节点的关系所以在MERGE和ON CREATE之后我必须使用WITH .... CREATE来创建关系,这就是问题...... WITH不在'范围内'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的“范围”中,因为重复将被跳过。任何帮助做这项工作将不胜感激。
[更新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
。
好的......所以FOREACH和CASE都没有做到这一点。实际上WHERE子句做了。我在问题中所述的原始需求是接受电子邮件列表,创建节点,其中列表中的电子邮件不存在节点,并返回创建的电子邮件节点的列表以及计数的数量....并没有失败的'电子邮件已经存在...'错误CATCH声明。这是我集合的解决方案:
MATCH(s:Person {email: 'mike@gmailxxx.com'})
WITH s, ['abcd123@abc.com','abcd123@abc.com','abcd456@abc.com','michael@abc.com'] 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的建议以及他对可能解决方案的迭代。
以上是关于如何在Neo4j中创建节点时跳过重复节点的主要内容,如果未能解决你的问题,请参考以下文章