2016-05-14 6 views
2

У меня есть простая модель шахматного турнира. Он имеет 5 игроков, играющих друг друга. График выглядит следующим образом:Удалить избыточные двусторонние отношения на графике Neo4j

enter image description here

граф, как правило, хорошо, но при дальнейшем осмотре, вы можете увидеть, что оба набора
Guy1 против guy2,
и
Guy4 против Guy5
есть избыточные отношения.

Проблема, очевидно, в данном, где есть посторонняя комплементарная строка для каждого из этих матчей (так что в некотором смысле это вопрос качества данных в базовом формате CSV):

enter image description here

Я мог бы очистить эти строки вручную, но реальный набор данных имеет миллионы строк. Так что мне интересно, как я могу удалить эти отношения в любой из 2-х способов, с помощью 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) 
+0

Это напрямую не связано с вашей проблемой, но в этих запросах есть много посторонних статей. 1. Партии 'ON CREATE blah' /' ON MATCH blah' могут быть заменены только одним 'blah'. 2. Ни одно из предложений WITH WITH не предназначено и может быть удалено. – cybersam

+0

Для # 1, какой предпочтительный синтаксис? –

+0

Поскольку вы хотите выполнять точно такие же операции 'SET', независимо от того, создал ли« MERGE »новый узел или сопоставил существующий узел, вы не должны использовать' ON MATCH' и 'ON create' вообще. Просто выполните две разные операции 'SET':' SET p.name = line.name, p.residence = line.residence'. – cybersam

ответ

7

Очевидно, что вам не нужны эти дополнительные отношения, как это не добавляет никакой ценности ни веса на графике.

Есть сведения, о которых мало кто знает, несмотря на то, что они находятся в документации.

MERGE можно использовать на undirected отношениях, neo4j выберет для вас одно направление (так как realtionships ДОЛЖНЫ быть направлены на графике).

Документация ссылка: 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) 

Это создаст отношения, поскольку она не существует. Однако, если вы запустите его во второй раз, ничего не изменится и не будет создано.

Я думаю, это решит вашу проблему, так как вам не придется беспокоиться о том, чтобы очистить данные в начале и запустить скрипты после очистки графика.

+0

Не каждый игрок в конечном итоге играет друг с другом (например, если вы посмотрите на график, вы можете видеть, что Guy3 и Guy5 на самом деле не играют). Будет ли этот код отрезанным создать это несуществующее совпадение? –

+0

Ну, если в вашем файле edge.csv нет строки, представляющей связь между Guy3 и Guy5, нет, она не будет создана. –

+0

А, я понимаю, что вы имеете в виду. Что-то вроде 'MATCH (p1: Player {player_id: line.player1_id}), (p2: Player {player_id: line.player2_id}) MERGE (p1) - [: VERSUS] - (p2)'. Я все еще получаю это предупреждение, которое я видел раньше: «Этот запрос создает декартовое произведение между несвязанными шаблонами». –

2

Я бы предложил создать «матч» узел как так

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

, чтобы включить детали отслеживания о матче отдельно от игроков.

Если вам необходимо отслеживать игрок матчи отличается от матчей самого, то

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

будет делать трюк.

+1

Я планировал использовать края для хранения информации о матчах ... были ли вы рекомендовать изменение схемы? Я бы предпочел сохранить его таким, какой он есть, и просто удалите лишние вещи. –

+0

Тим - Хотя может быть хорошим предложением иметь узел Match (или, по крайней мере, сделать интересное обсуждение), предполагая, что это не отвечает на основной вопрос об устранении избыточных отношений. –

+0

При всем уважении ключевой вопрос заключается не в избыточных отношениях, а в том, как организована схема. –

2

Если схема должна оставаться как есть, и единственным требованием является то, чтобы удалить избыточные связи, то

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

должен сделать трюк. Это находит все p1, p2 узлы с двунаправленными отношениями VERSUS и удаляет один из них.

+0

Должно быть MATCH (p1: Player) - [r1: VERSUS] -> (p2: Player) - [r2: VERSUS] -> (p1) WHERE id (p1) nmervaillie

Смежные вопросы