Как я могу найти и удалить узлы, для которых существуют два из заданных отношений? - PullRequest
1 голос
/ 20 июня 2020

У меня есть требование, чтобы в моей базе данных некоторые узлы имели не более одного отношения данного типа. Например, узлы с меткой Heart должны быть подключены через has максимум к одному узлу с меткой Body.

Вот некоторые тестовые данные для иллюстрации проблемы:

CREATE (h:Heart {animal: "zebra"})
CREATE (b1:Body {animal: "zebra"})
CREATE (b2:Body {animal: "elephant"})
CREATE (b1)-[:has]->(h)
CREATE (b2)-[:has]->(h)

CREATE (h2:Heart {animal: "mouse"})
CREATE (b4:Body {animal: "mouse"})
CREATE (b5:Body {animal: "leopard"})
CREATE (b4)-[:has]->(h2)
CREATE (b5)-[:has]->(h2)

С помощью следующего запроса я могу найти все узлы с соединениями, которые не соблюдают это правило:

MATCH (n:Heart) WHERE (:Body)-[:has]-(n)-[:has]-(:Body) RETURN n

Я бы хотел написать оператор для удаления «лишних» отношений. Прямо сейчас у меня есть запрос на удаление узлов, составляющих эти "лишние" отношения, но он также удаляет узлы, которые я хотел бы сохранить (по одному от каждого).

MATCH (b1:Body)-[:has]-(n)-[:has]-(b2:Body) DETACH DELETE b1, b2

Это тоже не ' t групповых отношений центральным узлом, поэтому я не могу удалить все узлы, кроме одного, так как это не даст желаемого эффекта.

Кто-нибудь знает, как я могу написать оператор, который удалит все "лишние "отношения, пока не останется только одно отношение has для каждого узла Heart? Желательно самый старый.

Ответы [ 2 ]

2 голосов
/ 20 июня 2020

Приведенный ниже оператор удаляет все отношения, кроме одного. Вам нужно будет добавить logi c, чтобы определить, какой из них вы хотите сохранить:)

MATCH (:Body)-[r:has]->(h:Heart)
WITH h,COLLECT(r) AS rs
WHERE SIZE(rs)> 1
FOREACH (r IN rs[1..] |
    DELETE r
)
1 голос
/ 20 июня 2020

Возможно, вы сможете удалить дополнительные вложения с помощью следующего кода

MATCH (b:Body)-[r:has]->(h:Heart)
WITH b, h
ORDER BY id(b)   // you can order it by something else if you have a better created date identifier
WITH collect(b) as bodies, h   // collect turns nodes into a list
WHERE size(bodies) > 1   // size is how large the list is
WITH tail(bodies) as bodies, h   // tail grabs all elements except first
UNWIND bodies as b   // turns them back into individual nodes
WITH b, h
MATCH (b)-[r:has]->(h)
DELETE r;

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...