删除 Neo4j 图中冗余的双向关系

Remove redundant two way relationships in a Neo4j graph

我有一个国际象棋锦标赛的简单模型。它有 5 个玩家互相玩。该图如下所示:

图表总体上没有问题,但进一步检查后,您可以看到两组
Guy1 对 Guy2,

Guy4 vs Guy5
每个都有冗余关系。

问题显然出在数据中,其中每个匹配项都有一个无关的互补行(因此从某种意义上说,这是底层 csv 中的数据质量问题):

我可以手动清理这些行,但实际数据集有数百万行。所以我想知道如何使用 CQL 以两种方式之一删除这些关系:

1) 首先不要读入额外的关系

2) 继续创建额外的关系,但稍后将其删除。

在此先感谢您对此的任何建议。

我使用的代码是这样的:

/ Here, we load and create nodes

LOAD CSV WITH HEADERS FROM
'file:///.../chess_nodes.csv' AS line
WITH line
MERGE (p:Player {
  player_id: line.player_id
})

ON CREATE SET p.name = line.name
ON MATCH SET p.name = line.name

ON CREATE SET p.residence = line.residence
ON MATCH SET p.residence = line.residence

// Here create the edges

LOAD CSV WITH HEADERS FROM
'file:///.../chess_edges.csv' AS line
WITH line
MATCH (p1:Player {player_id: line.player1_id})
WITH p1, line
OPTIONAL MATCH (p2:Player {player_id: line.player2_id})
WITH p1, p2, line
MERGE (p1)-[:VERSUS]->(p2)

很明显,您不需要这种额外的关系,因为它不会为图表增加任何价值或权重。

尽管文档中有一些内容,但很少有人知道。

MERGE 可用于 undirected 关系,neo4j 将为您选择一个方向(因为关系必须在图中定向)。

文档参考:http://neo4j.com/docs/stable/query-merge.html#merge-merge-on-an-undirected-relationship

以下语句的示例,如果您 运行 是第一次使用它:

MATCH (a:User {name:'A'}), (b:User {name:'B'}) 
MERGE (a)-[:VERSUS]-(b)

它将创建关系,因为它不存在。但是,如果您 运行 第二次,则不会更改或创建任何内容。

我想这会解决您的问题,因为您不必担心预先清理数据,也不必担心事后 运行 脚本清理图表。

我建议像这样创建一个 "match" 节点

(x:Player)-[:MATCH]->(m:Match)<-[:MATCH]-(y:Player) 

启用与球员分开的比赛详细信息跟踪。

如果您需要跟踪不同于比赛本身的球员比赛,那么

(x:Player)-[:HAS_PLAYED]->(pair:HasPlayed)<-[:HAS_PLAYED]-(y:Player)

就可以了。

如果架构必须保持原样并且唯一的要求是删除冗余关系,那么

MATCH (p1:Player)-[r1:VERSUS]->(p2:Player)-[r2:VERSUS]->(p1)
DELETE r2

应该可以解决问题。这将找到具有双向 VERSUS 关系的所有 p1、p2 节点并删除其中一个。

你需要使用 UNWIND 来完成这个技巧。

MATCH (p1:Player)-[r:VERSUS]-(p2:Player)
WITH p1,p2,collect(r) AS rels
UNWIND tail(rels) as rel
DELETE rel;

前面的代码将使用match 找到p1 和p2 之间类型为VERSUS 的直接连接(注意这不是定向的)。然后将获得关系的集合,最后是那些关系中的最后一个,它被删除。 当然可以加个check,看看collection的长度是不是2。