首页 > 解决方案 > neo4j 创建子节点并将其链接到另一个子节点

问题描述

意图:

使用 neo4j,我想将子节点添加到父节点。如果还有其他现有的孩子,我必须将孩子链接到所有兄弟姐妹

我试过的:

假设我们确定 Parent 存在。我们想在它下面添加通用节点。我得到了这个并修改了它: 这里

match(tbl: Parent {name: "existing_node"})
optional match(c: Child {name: "generic_node"})
create(n: Child{name: "generic_node"})
FOREACH (o IN CASE WHEN c IS NOT NULL THEN [c] ELSE [] END |
  CREATE (o)-[:SIBLING]->(n)
  CREATE (n)-[:SIBLING]->(o)
  )

问题描述:

如果我多次运行查询,则会发生以下情况:

  1. 创建一个新节点
  2. 创建一个新节点并将其与前一个节点链接
  3. 创建 2 个新节点并将其中一个链接到现有节点和新创建的节点。我期待它只创建 1 个节点并将其链接到所有其他节点。
  4. 创建 4 个新节点,并将其中一个连接到现有节点,并将它们连接为链。我期望只有 1 个节点被创建并链接到所有其他节点。

...

我不明白的是为什么要创建许多新节点?在 中FOREACH,我在想这(n)将引用同一个新创建的节点而不是创建新节点。

标签: neo4jcypher

解决方案


这应该可以满足您的要求(无论查询执行多少次,它都不会创建重复项):

// Find the parent, p
MATCH (p:Parent {name: "existing_node"})

// Find or create Child, c, and ensure it is associated with p
MERGE (c:Person {name: "generic_node"})
MERGE (p)-[:HAS_CHILD]->(c)

// Find each child of p (other than c), and ensure it has a `SIBLING` relationship with c
WITH p, c
MATCH (p)-[:HAS_CHILD]->(n)
WHERE n <> c
MERGE (c)-[:SIBLING]-(n)

请注意,无需SIBLING在每对兄弟节点之间建立两个关系(每个方向一个),因为稍后您可以使用MATCH不关心方向性的非定向查询。例如:

// Relationship pattern has no arrow, so matches relationship going in either direction
MATCH (c1:Child)-[:SIBLING]-(c2:Child)
...

同样,上面的子句也没有指定箭头,以确保 1和MERGE (c)-[:SIBLING]-(n)之间仅创建一个关系。cn


推荐阅读