Graph 基于公共属性将节点组合为单个节点
我正在努力学习更多关于Neo4j的知识。是否有方法将具有相同名称/编号/等的节点分组 在标准RDBMS中,可以使用“GROUPBY”子句将特定值组合成一个值。为了更好地理解,请看一看图片 我想将这两个节点(“EE”、“EE”)组合成一个节点,它有两个子节点 图像输出的代码:Graph 基于公共属性将节点组合为单个节点,graph,neo4j,group-by,cypher,Graph,Neo4j,Group By,Cypher,我正在努力学习更多关于Neo4j的知识。是否有方法将具有相同名称/编号/等的节点分组 在标准RDBMS中,可以使用“GROUPBY”子句将特定值组合成一个值。为了更好地理解,请看一看图片 我想将这两个节点(“EE”、“EE”)组合成一个节点,它有两个子节点 图像输出的代码: match (A:Place)-[:`->`]-(B:Typ) where A.name ='City1' return A, B 在Cypher中,SQL的GROUPBY子句没有等价物,因为它是隐式完成的。因此,
match (A:Place)-[:`->`]-(B:Typ)
where A.name ='City1'
return A, B
在Cypher中,SQL的
GROUPBY
子句没有等价物,因为它是隐式完成的。因此,无论何时使用,例如count
、sum
、min
或collect
,元组中的其余变量都会隐式分组
MATCH (a:Place {name: 'City1'})-[:`->`]-(b:Typ)
RETURN a.name, count(b)
然而,在我看来,您实际上想要执行一个将父节点组合在一起的转换(我们可以说节点是“合并”在一起的,但我想避免使用这个词,因为在Cypher中有一个具有不同语义的MERGE
子句——有关详细信息,请参见@cybersam的回答)
name
属性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'})
这导致:
并合并为:
在Cypher中,SQL的
GROUPBY
子句没有等价物,因为它是隐式完成的。因此,无论何时使用,例如count
、sum
、min
或collect
,元组中的其余变量都会隐式分组
MATCH (a:Place {name: 'City1'})-[:`->`]-(b:Typ)
RETURN a.name, count(b)
然而,在我看来,您实际上想要执行一个将父节点组合在一起的转换(我们可以说节点是“合并”在一起的,但我想避免使用这个词,因为在Cypher中有一个具有不同语义的MERGE
子句——有关详细信息,请参见@cybersam的回答)
name
属性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'})
这导致:
并合并为:
当您创建
位置
节点时,您应该使用一个操作而不是。例如,无论执行以下操作多少次,如果已经存在同名的节点,则不会创建重复的Place
节点:
MERGE (a:Place {name: 'City1'})
...
另外,在使用合并
操作之前,应首先在:Place(name)
(或在同一节点标签和属性上创建一个)上创建一个操作,使其以最佳方式工作。在创建Place
节点时,应使用一个操作,而不是。例如,无论执行以下操作多少次,如果已经存在同名的节点,则不会创建重复的Place
节点:
MERGE (a:Place {name: 'City1'})
...
另外,在使用MERGE
操作之前,您应该先创建一个on:Place(name)
(或在同一节点标签和属性上创建一个)。以防您不知道:如果您希望将节点永久合并为1合并关系,您可以使用。如果所有属性(内部节点id除外)都相同,则可能是
CALL apoc.refactor.mergeNodes([node1, node2])
以防您不知道:如果您希望将节点永久合并到1中,同时合并关系,您可以使用。如果所有属性(内部节点id除外)都相同,则可能是
CALL apoc.refactor.mergeNodes([node1, node2])
我想问一下,为什么您要使用像->
这样的关系类型,而不是将这些信息编码到关系的方向?实际上,您的图像揭示了一个有趣的问题,即->
作为关系类型。web UI可以将关系类型旋转180°。当关系类型由普通的字母、数字和下划线组成时,这并没有多大区别。但是,->
旋转会给您提供准确的。此外,如果您需要有多个关系类型,您必须为新类型提供“普通”名称。之后,->
类型名称会变得模棱两可。我想问一下,为什么您要使用像->
这样的关系类型,而不是将这些信息编码到关系的方向?实际上,您的图像揭示了一个有趣的问题,将->
作为关系类型。web UI可以将关系类型旋转180°。当关系类型由普通的字母、数字和下划线组成时,这并没有多大区别。但是,->
旋转会给您提供准确的。此外,如果您需要有多个关系类型,您必须为新类型提供“普通”名称。之后,->
类型名称将不明确。是的,我想执行一个组合父节点的转换。我是怎么做到的?@DevMaster:我用这样一个查询扩展了我的解决方案。你是最好的。还有一件事,它似乎可以工作,但缺少父节点“名称”。知道为什么吗?你必须分别复制那个(可能还有其他属性)。我只是在添加一个示例时才注意到它——它现在应该可以工作了。是的,我想执行一个组合父节点的转换。我是如何做到这一点的?@DevMaster:我用这样一个查询扩展了我的解决方案。你是最棒的,就一个mo