Neo4j - Cypher:合并重复关系

时间:2013-09-10 17:04:32

标签: neo4j cypher graph-databases

我在节点之间有重复的关系,例如:

A ->{weight: 1} B
A ->{weight: 1} B
A ->{weight: 1} B

我希望将这些关系合并为一个形式的关系:A-> {weight:3} B用于我的整个图形。

我尝试过以下内容:

start n = node(*) 
match (n)-[r:OCCURENCE]->()
Set r.weight = count(*)
count(*)

但是我的图表非常大,并且每个节点A和B的查询边缘都会更新两次。此外,旧关系不会被删除。不知道如何在一个查询中对这两个方面进行建模。希望有人可以提供帮助。

编辑:

用节点()和关系()尝试了其他一些查询,例如

start n = node(*) match ()-[r:OCCURENCE]->() set n.SumEdgeWeight = sum(r.weight)

他们处理的速度很慢。当我需要更新所有节点时,还有其他更快的方法吗?我在Neo4j社区找到了这个主题[1]。我的查询是否有可能更快地运行java核心api?

[1] https://groups.google.com/forum/#!topic/neo4j/4SSxvNsuQsY

的问候。

2 个答案:

答案 0 :(得分:7)

您可以从您所追求的更具体的模式(node(*))开始,而不是以匹配每个节点(A-[:OCCURRENCE]->B)的非常一般的模式开始。这可能会加快速度。

不是计算节点以达到总重量,而是可以聚合权重值(您似乎在编辑中转向,但您将权重聚合设置为节点上的属性)。也许你的数据所有的关系都有1的权重,如果有的话,某种计数可以起作用(你可以尝试计算关系而不是节点),但是可能值得一个不能产生正确结果的查询偶然。这样的查询也可以使用不同的权重值,例如,如果您将来导入更多数据并且需要合并新的[OCCURRENCE]关系(可能权重为1),并且已经合并到位。

你能尝试这样的事吗?

MATCH A-[r:OCCURRENCE]->B
WITH A, COLLECT(r) as oldRels, B, SUM(r.weight) as W
FOREACH(r IN oldRels | DELETE r)
WITH A, W, B
CREATE A-[O:OCCURRENCE {weight:W}]->B;

我将此查询的含义类似于:对于图表中的所有A-[r:OCCURRENCE]->B模式,COLLECT关系并带来该集合WITH,以便稍后删除它们。同时带来WITH相关节点和关系权重的SUM。旧关系的FOREACH,删除它,并仅WITH两个节点和聚合权重。创建新关系并将权重设置为聚合权重。

答案 1 :(得分:1)

虽然这是一个老问题,但是这里可以使用一些新的apoc功能。您需要为您的neo版本安装apoc插件。

MATCH (A)-[r:OCCURRENCE]->(B) 
WITH  A,B,collect(distinct(r.weight)) as values, count(r) as relsCount
MATCH (A)-[r:OCCURRENCE]->(B)
WHERE size(values) = 1 AND relsCount > 1 
WITH A,B,collect(r) as rels
CALL apoc.refactor.mergeRelationships(rels,{properties:"combine"})
YIELD rel RETURN rel

"结合" property返回数组中每个重复关系的权重,您可以求和。或者,您可以先按照前面的示例将关系添加到关系中,然后删除此属性。

更多文档here