2014-10-29 2 views
1

У меня есть граф, который состоит из одного центрального узла и большого числа других узлов, подключенных к центральному. Я хотел бы удалить узлы транзакционным способом, то есть начать с внешних узлов, удалить их в пакетах, скажем, по 5K каждый, и продолжить движение в центр.Как постепенно удалить узлы из графика

Вот ссылка на консоль, которая содержит небольшой иллюстративный граф http://console.neo4j.org/?id=vwphbn для справки.

Моя проблема заключается в том, чтобы сопоставлять узлы, у которых нет других отношений, которые связывают их (косвенно) с центральным узлом.

Обновление. Я думаю, что некоторое объяснение поможет. У меня есть большой иерархический набор данных, который нужно удалить в кусках, но с обычным способом (повторять это:

MATCH (n: Root {rootId : {rootId}}) 
OPTIONAL MATCH n-[r]-x 
DELETE r,x 
RETURN count(*) 

в то время как count > 0) может вызвать удаление самого Root и некоторых дочерних узлов будут оставлены сиротами с нет средств для их обнаружения и удаления, я думаю, должен быть какой-то способ, в котором я все же могу удалить куски графа более или менее дешево, и в то же время иметь некоторый порядок и сохранить краеугольный корень узла.

ответ

2

Использование примера график, следующий запрос будет подрезать график в партиях, как ожидалось:

MATCH p=(n1:Node)<-[r*]-(n2) 
WHERE NOT (n2)<--() 
WITH last(nodes(p)) AS n 
LIMIT 5000 
MATCH (n)-[r]->() 
DELETE r, n 

Стоит отметить, что первый MATCH оператор в этом запросе вызовет проблемы производительности в масштабе. Чтобы решить эту проблему, вы можете применить ярлык для всех узлов, подключенных к корневому узлу, а затем выполните следующие действия:

MATCH (n1:Nodes) 
WHERE NOT (n1)<--() 
LIMIT 5000 
MATCH (n)-[r]->() 
DELETE r, n 

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

Update:

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

MATCH p=(n1:Node)<-[r*]-(n2) 
WHERE NOT (n2)<--() 
WITH nodes(p) AS slices 
LIMIT 1 UNWIND slices AS n 
MATCH (n)-[r]->() 
DELETE r, n 
+0

Дело в том, есть больше, чем на таких «кругов» в базы данных, поэтому я не могу сопоставлять только ярлык. Но вы вдохновили меня на разработку другого подхода, который исключает сущности не в этом «концентрическом» способе, а скорее так, как вы бы нарезали пирог: совпадение с путём «MATCH (r: Root) - [rel ] - (n), p = ((n) - [r *] - (k)) ', а затем удалить' rel' и 'p', что оставит меня с самим корнем после того, как все« срезы »будут был «разрезан». Этот подход стоит попробовать? А так как p будет соответствовать всем путям типа '(a)', '(a) - (b)', '(a) - (b) - (c)' и т. Д., Может быть, лучше ... – tkroman

+0

... чтобы собрать все узлы из путей, сделать «DISTINCT» на них, а затем удалить их внутри блока «FOREACH»? – tkroman

+0

Мне очень нравится эта идея. Вот запрос я рекомендовал бы использовать UNWIND: СПИЧКА р = (n1: Узел) <- [R *] - (П2) ГДЕ НЕ (п2) <-() с узлами (р) ломтиков LIMIT 1 UNWIND slices AS n MATCH (n) - [r] ->() DELETE r, n –

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