如何在 Neo4j 中使用 Cypher 合并同一社区的节点?

问题描述 投票:0回答:1

有一个图,它的每个节点都包含属性

communityId
来指示该节点属于哪个社区。节点之间以
LINK
关系连接,其中包含
weight
属性。

我想要的是将那些同一个社区的节点合并成一个大节点。这些大节点(又名社区)之间的链接必须合理地合成/组合:链接的

weight
属性必须根据每个社区中相互连接的各个节点进行累加。必须尊重链接的方向。

在结果图中,我只会看到连接的 community 节点。

最接近的函数是Merge Nodes,函数

apoc.refactor.mergeNodes()
。然而,我对结果不满意,因为:

  • 问题1:结果社区节点有自链。
  • 问题 2:尽管文档如此说明,但链接的权重并未合并。

问题1可以通过再编写一个Cypher来删除自链接来解决。但问题 2 只能通过对图的低级访问来解决(如上面的

mergeNodes()
)。

是否有任何优雅的方法可以一次性获得我想要的图表(社区节点)?或者至少,问题 2 必须以某种方式得到解决。

再现性

图表:

CREATE (a:User {name: "A", communityId: 2}), (b:User {name: "B", communityId: 2}), (c:User {name: "C", communityId: 2}), (x:User {name: "X", communityId: 1}), (y:User {name: "Y", communityId: 1}), (z:User {name: "Z", communityId: 1}), (w:User {name: "W", communityId: 1}), (a)-[:LINK {weight: 1}]->(b), (b)-[:LINK {weight: 1}]->(c), (c)-[:LINK {weight: 1}]->(a), (b)-[:LINK {weight: 1}]->(z), (z)-[:LINK {weight: 1}]->(x), (z)-[:LINK {weight: 1}]->(w), (w)-[:LINK {weight: 1}]->(y), (y)-[:LINK {weight: 1}]->(x), (b)-[:LINK {weight: 1}]->(w)

密码:

MATCH (n:User) WITH n.communityId AS communityId, COLLECT(n) AS nodes CALL apoc.refactor.mergeNodes(nodes, { properties: { name: 'combine', communityId: 'discard', weight: 'combine' }, mergeRels: true }) YIELD node RETURN node

系统要求

    Windows 8.1 x64
  • Neo4j 桌面 v1.3.4(引擎 v4.1.1。)
  • APOC v4.1.0.2
  • 图数据科学库 v1.3.2
neo4j cypher neo4j-apoc
1个回答
0
投票
我不太清楚为什么 APOC 没有合并你的示例中的关系。不过,这里有一个 Cypher 查询可以帮助您入门:

MATCH (n:User)-[r]->(v:User) WHERE n.communityId <> v.communityId // discard self loop WITH n.communityId as comId1, v.communityId as comId2, sum(r.weight) as w MERGE (su1:SuperUser {communityId: comId1}) // create or get merged node for n.communityId MERGE (su2:SuperUser {communityId: comId2}) // create or get node for v.communityId MERGE (su1)-[r:SUPER_LINK]->(su2) ON CREATE SET r.weight = w // set relationship weight when it is created RETURN su1, su2, r
创建以下节点和关系:

© www.soinside.com 2019 - 2024. All rights reserved.