如何在Neo4j中创建节点时跳过重复节点

问题描述 投票:0回答:2

我有一个用于创建节点的电子邮件地址列表。但是,如果其中一个电子邮件地址已经存在,我不希望获得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的“范围”中,因为重复将被跳过。任何帮助做这项工作将不胜感激。

javascript node.js neo4j cypher
2个回答
1
投票

[更新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 [] ENDi时,NULL将返回非空列表。
  • 如果列表为空,则FOREACH子句不会执行其包含的write子句。否则,它将执行所有这些。
  • 在开始时,此查询首先获得从orig_count传出的原始INVITED关系数的计数(s)。
  • 最后,它得到一个最终计数,并从中减去orig_count得到new_relationship_count

0
投票

好的......所以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的建议以及他对可能解决方案的迭代。

© www.soinside.com 2019 - 2024. All rights reserved.