添加连接到一组新添加的节点的新节点

Adding new node connected to set of newly added nodes

我需要一个执行以下操作的查询:

  1. 如果节点不存在,则插入可变数量的节点
  2. 如果还没有一个节点与 1 中添加的所有节点有关系,则创建此节点并将其连接到来自一个节点的节点

一般的想法是,可变数量的节点描述了我想通过插入新节点来聚合的唯一事件。 所以如果我先通过这个

插入 4 个节点
MERGE (k:type1 {data: "data1"})
MERGE (a:type2 {data: "data2"})
MERGE (m:type3 {data: "data3l"})
MERGE (p:type4 {data: "data4s"})
WITH [a, m, p, k] AS myList
CALL apoc.lock.nodes(myList) // let's lock ahead this time
WITH head(myList) as first, myList
OPTIONAL MATCH (d:SomeLabel)-[:REL]->(first)
WHERE all(node in tail(myList) WHERE (d)-[:REL]->(node))
WITH first, myList
WHERE d IS NULL
MERGE (d:SomeLabel)-[:REL]->(first)
FOREACH (node in tail(myList) | MERGE (d)-[:REL]->(node))

如果我更改第一个节点,图形将按预期显示:

MERGE (a:type2 {data: "data2"})
MERGE (m:type3 {data: "data3l"})
MERGE (p:type4 {data: "data4s"})
WITH [a, m, p, k] AS myList
CALL apoc.lock.nodes(myList) // let's lock ahead this time
WITH head(myList) as first, myList
OPTIONAL MATCH (d:SomeLabel)-[:REL]->(first)
WHERE all(node in tail(myList) WHERE (d)-[:REL]->(node))
WITH first, myList
WHERE d IS NULL
MERGE (d:SomeLabel)-[:REL]->(first)
FOREACH (node in tail(myList) | MERGE (d)-[:REL]->(node))

Correct graph

但是,例如更改第二个节点的内容时,不会添加新的公共节点

MERGE (k:type1 {data: "data1"})
MERGE (a:type2 {data: "data22"})
MERGE (m:type3 {data: "data3l"})
MERGE (p:type4 {data: "data4s"})
WITH [a, m, p, k] AS myList
CALL apoc.lock.nodes(myList) // let's lock ahead this time
WITH head(myList) as first, myList
OPTIONAL MATCH (d:SomeLabel)-[:REL]->(first)
WHERE all(node in tail(myList) WHERE (d)-[:REL]->(node))
WITH first, myList
WHERE d IS NULL
MERGE (d:SomeLabel)-[:REL]->(first)
FOREACH (node in tail(myList) | MERGE (d)-[:REL]->(node))

Incorrect graph

此外,完成此操作后我想添加另一个连接到新公共节点的节点

我使用@Graphileon 的答案作为我的解决方案

MERGE (a:type2 {data: "data2"})
MERGE (m:type3 {data: "data3l"})
MERGE (p:type4 {data: "data4s"})
WITH [a, m, p, k] AS things
OPTIONAL MATCH (c:Collection)
WHERE apoc.coll.isEqualCollection([(c)-[:REL]->(thing)|thing],things)
WITH things,COALESCE(id(c),-1) AS idC, id(c) as center

CALL apoc.do.when(
      idC = -1,
      'CREATE (c:Collection) '
      + 'FOREACH(m IN $things | MERGE (c)-[:REL]->(m) ) '
      + 'MERGE (s:sample)-[:REL]->(c)',
      '',
      {things:things}
) YIELD value
RETURN value.node as node;

你考虑过这种方法吗:

WITH ['a','b','c','d'] AS thingNames
FOREACH( thingName in thingNames |
    MERGE (n:Thing {name:thingName})
) 
WITH thingNames
MATCH (n:Thing) WHERE n.name IN thingNames
WITH COLLECT(n) AS things
OPTIONAL MATCH (c:Collection)
WHERE apoc.coll.isEqualCollection([(c)-[:REL]->(thing)|thing],things)
WITH things,c,COALESCE(id(c),-1) AS idC

CALL apoc.do.when(
      idC = -1,
      'CREATE (c:Collection) '
      +' FOREACH(m IN $things | MERGE (c)-[:REL]->(m) )'
      +' RETURN c',
      '',
      {things:things}
) YIELD value

RETURN COALESCE(c, value.c) AS collectionNode

它为事物的每个新组合创建一个新的:Collection节点