添加连接到一组新添加的节点的新节点
Adding new node connected to set of newly added nodes
我需要一个执行以下操作的查询:
- 如果节点不存在,则插入可变数量的节点
- 如果还没有一个节点与 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
节点
我需要一个执行以下操作的查询:
- 如果节点不存在,则插入可变数量的节点
- 如果还没有一个节点与 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
节点