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

时间:2016-05-14 21:18:15

标签: neo4j cypher tournament

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

enter image description here

图表通常很好,但经过进一步检查,你可以看到两套都有 Guy1 vs Guy2,

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

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

enter image description here

我可以手动清理这些行,但真正的数据集有数百万行。所以我想知道如何使用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)

4 个答案:

答案 0 :(得分:7)

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

尽管存在于文档中,但很少有人知道这一点。

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)

它将创建不存在的关系。但是,如果再次运行它,则不会更改或创建任何内容。

我想这可以解决您的问题,因为您不必担心提前清理数据,也不必为了清理图表而运行脚本。

答案 1 :(得分:2)

我建议创建一个"匹配"像这样的节点

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

启用与玩家分开的有关匹配的详细信息。

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

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

会做到这一点。

答案 2 :(得分:1)

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

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

应该做的伎俩。这将查找具有双向VERSUS关系的所有p1,p2节点,并删除其中一个节点。

答案 3 :(得分:0)

您需要使用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类型的直接连接(请注意,这不是定向的)。然后将获取关系的集合,最后是这些关系的最后一个,将其删除。 当然,您可以添加检查以查看集合的长度是否为2。