简体   繁体   English

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

[英]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: The result community nodes have self-link.问题一:结果社区节点有自链接。
  • Problem 2: Weights of the links are not combined although the documentation says so.问题 2:尽管文档如此说明,但链接的权重并未合并。

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。

Reproducibility再现性

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

在此处输入图片说明

System Requirement系统要求

  • Windows 8.1 x64视窗 8.1 x64
  • Neo4j Desktop v1.3.4 (Engine v4.1.1.) Neo4j 桌面 v1.3.4 (引擎 v4.1.1.)
  • APOC v4.1.0.2 APOC v4.1.0.2
  • Graph Data Science Library v1.3.2图数据科学图书馆 v1.3.2

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM