【问题标题】:Adding new node connected to set of newly added nodes添加连接到新添加节点集的新节点
【发布时间】:2022-01-22 20:38:17
【问题描述】:

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

  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;

【问题讨论】:

    标签: graph neo4j cypher neo4j-apoc


    【解决方案1】:

    您是否考虑过这种方法:

    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 节点

    【讨论】:

    • 谢谢。我用你的方法得到了一个适合我的查询。如果集合节点已经存在,我该如何使用它。在那种情况下,我想做类似MERGE (s)-[:REL]->(c)
    • @newjoiner1234 你能定义“使用”吗?从您的问题来看,似乎不必合并或创建某些东西。顺便说一句,如果我的回答可以解决您的问题,请接受。
    • 我对 cypher 很陌生,但我希望我能知道我想做什么 ``` CALL apoc.do.when(idC = -1, 'CREATE (c:Collection) ' + 'FOREACH(m IN $things | MERGE (c)-[:REL]->(m) ) ' + 'MERGE (s:sample)-[:REL]->(c)', 'MERGE (s :samp)-[:REL]->(c)', {things:things} ) YIELD 值```
    • 我更新了答案,以便在任何情况下,它都会返回集合节点。
    猜你喜欢
    • 2021-12-09
    • 1970-01-01
    • 2014-05-14
    • 2015-09-08
    • 1970-01-01
    • 2016-08-16
    • 1970-01-01
    • 2012-02-11
    • 1970-01-01
    相关资源
    最近更新 更多