[英]How to merge nodes of the same community with Cypher in Neo4j?
There is a graph, each of its nodes contains property communityId
to indicate which community the node belongs to.有一个图,它的每个节点都包含属性
communityId
来指示该节点属于哪个社区。 The nodes are connected with LINK
relationship, which contains weight
property.节点之间以
LINK
关系连接,其中包含weight
属性。
What I want is to merge those nodes of the same community into a big node.我想要的是将同一社区的那些节点合并成一个大节点。 The links between those big nodes (aka. communities) must be synthesized/combined reasonably : the
weight
property of the link must be added up, based on individual nodes in each community connected to the other.这些大节点(又名社区)之间的链接必须合理合成/组合:必须根据每个社区中相互连接的各个节点,将链接的
weight
属性相加。 Direction of the link must be respected.必须遵守链接的方向。
In the result graph, I will only see connected community nodes.在结果图中,我只会看到连接的社区节点。
The closest function is Merge Nodes , function apoc.refactor.mergeNodes()
.最接近的函数是Merge Nodes ,函数
apoc.refactor.mergeNodes()
。 However, I'm dissatisfied with the result because:但是,我对结果不满意,因为:
Problem 1 can be fixed by writing one more Cypher to remove self-links.问题 1 可以通过再编写一个 Cypher 来消除自链接来解决。 But problem 2 can only be tackled with low-level access to the Graph (like
mergeNodes()
above).但是问题 2 只能通过对 Graph 的低级访问来解决(如上面的
mergeNodes()
)。
Is there any elegant approach to have my desired graph ( community nodes) in one go ?有没有什么优雅的方法可以一次性获得我想要的图(社区节点)? Or at least, problem 2 must be fixed somehow.
或者至少,必须以某种方式解决问题 2。
Graph:图形:
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)
Cypher:暗号:
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
I am not quite sure why APOC is not merging the relationships in your example.我不太确定为什么 APOC 没有合并您示例中的关系。 However, here is a Cypher query to get you started:
但是,这里有一个 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
which creates the following nodes and relationship:这将创建以下节点和关系:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.