创建多个唯一关系neo4j(单个查询)

时间:2018-11-21 21:00:22

标签: neo4j cypher

我目前正在编写一个猫鼬插件,以使用javascript neo4j driver自动维护neo4j节点,并且目前正在将更新更新(保存部分工作于atm)映射到密码查询。

我目前停留在用例上,我想更新文档(一个:Class,另存为neo4j中的节点)和更新的引用(类型为:Person的学生)之间的多个关系,保存为neo4j中的不同节点),同时删除与旧参考相关的旧关系(在这种情况下为学生)。这是更新neo4j中的一系列子文档引用的结果。

除了在查询中创建的叉(笛卡尔)乘积外,主要问题是以下查询创建的关系是删除的关系的两倍:

MATCH (doc:Class {m_id: '5bf5b9df11c344021de89395'}), 
      (I:Person {m_id: '5bf5b9df11c344021de89393'}), 
      (II:Person {m_id: '5bf5b9df11c344021de89394'}), 
      (:Class {m_id: '5bf5b9df11c344021de89395'})-[r]->() 
WHERE type(r) IN ["HAS_STUDENT"] 
CREATE (doc)-[:HAS_STUDENT]->(I), (doc)-[:HAS_STUDENT]->(II) 
DELETE r;

这将删除2个关系(这是正确的),但会创建4个新关系(应为2个)。

使用CREATE形式的单个CREATE (I)<-[:HAS_STUDENT]-(doc)-[:HAS_STUDENT]->(II)也不是有效的选择,因为此查询是在for循环中创建的,并且可能会创建越来越多的新关系。 (也是我要优化查询的主要原因。)

我有该查询的多个版本,所有版本均产生相同的输出。问题可能出在WHERE部分,因为当我使用下面的查询时,它会创建正确数量的关系。 唯一缺少的是它应该只删除旧的关系

MATCH (doc:Class {m_id: '5bf5b9df11c344021de89395'}), 
      (I:Person {m_id: '5bf5b9df11c344021de89393'}), 
      (II:Person {m_id: '5bf5b9df11c344021de89394'}) 
CREATE (doc)-[:HAS_STUDENT]->(I), (doc)-[:HAS_STUDENT]->(II) 
WITH doc 
MATCH (doc)-[r]->(n) 
WHERE type(r) IN ["HAS_STUDENT"] 
DELETE r;

因此,除了解决问题外,我的主要问题是如何针对所描述的行为有效地编写此查询。我使用neo4j驱动程序,因此可以使用参数。

注意::I和II稍后将用作变量来分配唯一的关系值,这就是为什么我没有为MATCH节点使用单个:Person的原因。

还使用IN子句中的关系类型的WHERE,因为可能会创建不同类型的关系(并因此删除了该类型的旧关系)。

最后,我已经研究过UNWINDFOREACH,但似乎无法将它们放入所描述的用例中。

1 个答案:

答案 0 :(得分:2)

密码的问题是,每行

所以在这里

MATCH (doc:Class {m_id: '5bf5b9df11c344021de89395'}), // 1
      (I:Person {m_id: '5bf5b9df11c344021de89393'}), // 1
      (II:Person {m_id: '5bf5b9df11c344021de89394'}), // 1
      (:Class {m_id: '5bf5b9df11c344021de89395'})-[r]->() // 2
      // 1 match * 1 match  * 1 match * 2 match  = 2 rows
WHERE type(r) IN ["HAS_STUDENT"] 
CREATE (doc)-[:HAS_STUDENT]->(I), (doc)-[:HAS_STUDENT]->(II) 
// 2 create * 2 rows = 4 new relations
DELETE r;

因此,您需要先使用DISTINCT剪掉“重复的”行

MATCH (doc:Class {m_id: '5bf5b9df11c344021de89395'}), 
      (:Class {m_id: '5bf5b9df11c344021de89395'})-[r]->() 
WHERE type(r) IN ["HAS_STUDENT"] 
DELETE r;
WITH DISTINCT doc
MATCH (I:Person {m_id: '5bf5b9df11c344021de89393'}), 
      (II:Person {m_id: '5bf5b9df11c344021de89394'})
CREATE (doc)-[:HAS_STUDENT]->(I), (doc)-[:HAS_STUDENT]->(II)