如何在 Neo4j 中将同一社区的节点与 Cypher 合并?
How to merge nodes of the same community with Cypher in Neo4j?
有一个图,它的每个节点都包含属性 communityId
表示该节点属于哪个社区。节点以LINK
关系连接,其中包含weight
属性.
我想要的是将同一个社区的那些节点合并成一个大节点。那些大节点(又名社区)之间的 links 必须是 synthesized/combined 合理地 : weight
属性 link 必须加起来,基于每个社区中相互连接的各个节点。必须遵守 link 的方向。
在结果图中,我只会看到连接的社区个节点。
最接近的函数是Merge Nodes,函数apoc.refactor.mergeNodes()
。但是,我对结果不满意,因为:
- 问题一:结果社区节点有self-link.
- 问题 2:link 的权重没有合并,尽管文档中是这样说的。
问题 1 可以通过再编写一个 Cypher 来删除 self-link 来解决。但是问题 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 Desktop v1.3.4(引擎 v4.1.1。)
- APOC v4.1.0.2
- 图数据科学库 v1.3.2
我不太清楚为什么 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
创建以下节点和关系:
有一个图,它的每个节点都包含属性 communityId
表示该节点属于哪个社区。节点以LINK
关系连接,其中包含weight
属性.
我想要的是将同一个社区的那些节点合并成一个大节点。那些大节点(又名社区)之间的 links 必须是 synthesized/combined 合理地 : weight
属性 link 必须加起来,基于每个社区中相互连接的各个节点。必须遵守 link 的方向。
在结果图中,我只会看到连接的社区个节点。
最接近的函数是Merge Nodes,函数apoc.refactor.mergeNodes()
。但是,我对结果不满意,因为:
- 问题一:结果社区节点有self-link.
- 问题 2:link 的权重没有合并,尽管文档中是这样说的。
问题 1 可以通过再编写一个 Cypher 来删除 self-link 来解决。但是问题 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 Desktop v1.3.4(引擎 v4.1.1。)
- APOC v4.1.0.2
- 图数据科学库 v1.3.2
我不太清楚为什么 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
创建以下节点和关系: