如何在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 [] ENDi时,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中创建节点时跳过重复节点的主要内容,如果未能解决你的问题,请参考以下文章

在Neo4J中创建具有相同属性的节点之间的关系

在neo4j中创建一对多关系

在某些情况下无法从neo4j中检索id

Neo4J 在 Cypher 中创建临时变量

尝试放松并在节点之间建立新的关系Neo4J C#Client

在将节点从 csv 创建到 neo4j 时创建关系