基于公共属性将节点组合到单个节点

时间:2017-12-08 17:43:47

标签: graph neo4j group-by cypher

我试图了解有关Neo4j的更多信息。有没有办法对具有相同名称/编号/等的节点进行分组?

在标准RDBMS中,可以使用" Group by"将特定值组合成一个子句。看看图片以便更好地理解。

Image HERE

我希望将这两个节点(" EE"," EE")组合成一个节点,它有两个子节点。

图像输出代码:

match (A:Place)-[:`->`]-(B:Typ)
where A.name ='City1'
return A, B

3 个答案:

答案 0 :(得分:2)

创建Place个节点时,您应该使用MERGE操作而不是CREATE。例如,无论您执行以下操作多少次,如果已存在具有相同Place的节点,则不会创建重复的name节点:

MERGE (a:Place {name: 'City1'})
...

此外,在您使用MERGE操作之前,您应该通过首先:Place(name)(或index上创建uniqueness constraint来使其最佳运作在相同的节点标签和属性上)。

答案 1 :(得分:1)

Cypher中没有SQL语句GROUP BY子句的等价物,因为它是隐含的。因此,无论何时使用aggregating function,例如countsummincollect,元组中的其余变量都会被隐式分组。< / p>

MATCH (a:Place {name: 'City1'})-[:`->`]-(b:Typ)
RETURN a.name, count(b)

然而,在我看来,你真的想要执行一个将父节点组合在一起的转换(我们可以说节点是&#34;合并&#34;在一起,但我会喜欢避免这个词,因为Cypher中有一个MERGE条款具有不同的语义 - 请参阅@ cybersam的详细答案。

  1. 匹配所需的模式。
  2. 投射到属性,作为分组和分组的关键。
  3. 创建新的父节点。
  4. 为该节点创建name属性。
  5. 向新节点添加关系。
  6. 删除旧的父节点。
  7. 实际上,这可以使用如下查询来实现:

    MATCH (a:Place {name: 'City1'})-[:`->`]-(b:Typ)
    WITH a.name AS name, collect(a) AS as, collect(b) AS bs
    CREATE (new:Place {name: name})
    WITH as, bs, new
    UNWIND bs AS b
    CREATE (new)-[:`->`]->(b)
    WITH as
    UNWIND as AS a
    DETACH DELETE a
    

    虽然查询非常复杂,但幸运的是,很容易在玩具数据集上进行测试:

    CREATE
      (:Place {name: 'City1'})-[:`->`]->(:Typ {name: 'B1'}),
      (:Place {name: 'City1'})-[:`->`]->(:Typ {name: 'B2'})
    

    这导致:

    enter image description here

    并合并到:

    enter image description here

答案 2 :(得分:1)

万一你不知道:如果你想将节点永久合并为1合并关系,你可以使用APOC。如果所有属性(内部节点id除外)都相同,则可能。

CALL apoc.refactor.mergeNodes([node1, node2])