Neo4j Cypher: сопоставление и удаление подграфа на основе значения свойства узла

Предположим, у меня есть 3 подграфа в Neo4j, и я хотел бы выбрать и удалить весь подграф, если все узлы в подграфе соответствуют критериям фильтрации, которые являются значением свойства каждого узла ‹= 1. Однако, если есть по крайней мере один узел в подграфе, который не соответствует критериям, тогда подграф не будет удален.

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

идентификаторы пользователей и значения - это свойства узла.

введите здесь описание изображения

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


person sjishan    schedule 15.12.2016    source источник
comment
Под подграфом вы конкретно подразумеваете отключенный подграф?   -  person cybersam    schedule 16.12.2016
comment
Было бы полезно узнать, все ли задействованные узлы имеют одну и ту же метку или для этих узлов существует несколько меток. Если да, то индексируется ли свойство value?   -  person InverseFalcon    schedule 16.12.2016
comment
@InverseFalcon да узлы имеют метку. и свойство value также индексируется.   -  person sjishan    schedule 17.12.2016
comment
@cybersam да они отключены подграф   -  person sjishan    schedule 17.12.2016


Ответы (1)


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

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

MATCH (a:MyNode)
WHERE a.value <= 1
SET a:Dead

И отдельно

MATCH (a:MyNode)
WHERE a.value > 1
SET a:Alive

Тогда ваш запрос для отметки узлов для удаления будет:

MATCH (a:Dead)
WHERE NOT (a)-[*]-(:Alive)
SET a:ToDelete

И если все в порядке с узлами, которые вы отметили для удаления, вы можете запустить операцию удаления, используя apoc.periodic.commit () из процедур APOC, чтобы при необходимости выполнить операцию в пакетном режиме.

MATCH (a:ToDelete)
DETACH DELETE a

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

person InverseFalcon    schedule 16.12.2016
comment
Большое тебе спасибо. Работает отлично. В исходном варианте использования у меня будет около 70 миллионов узлов, и каждый день мне может понадобиться удалять 4-6 миллионов узлов. Так что я надеюсь, что все будет хорошо. Идея узла: Cluster довольно интересна, но я не уверен, осуществима ли она, учитывая, что новые узлы будут приходить каждый день. Итак, каждый раз, когда добавляется узел, потребуется поиск, чтобы узнать, нужно ли добавлять узел кластера. - person sjishan; 17.12.2016
comment
Когда вы добавляете новые узлы, знаете ли вы, будут ли они связаны с существующими кластерами или они будут создавать собственные кластеры? Если вы это знаете, вы можете включить шаг, на котором вы создаете узел: Cluster прямо перед добавлением нового узла. Кроме того, изменятся ли когда-нибудь ваши ценности? Если они собираются остаться такими же, возможно, стоит добавить любой подходящий ярлык (: Alive или: Dead, хотя: Dead, вероятно, следует использовать другое имя) во время создания. Если они изменятся, вам может потребоваться удалить эти метки после завершения операции удаления, чтобы вы не работали с устаревшими данными. - person InverseFalcon; 17.12.2016
comment
Нет, при добавлении новых узлов он не может образовывать новый кластер или новый кластер. Вот почему я использую для этого merge операцию. Вы можете рассматривать значение как метку времени, она не изменится, и удаление происходит на основе метки времени. Например, допустим, я поддерживаю данные графика в течение 10 дней, поэтому каждый день будут новые операции удаления и вставки. Новые узлы каждый день могут складываться со старым кластером или могут сами образовывать новый кластер. - person sjishan; 17.12.2016