Neo4j алгоритм возврата графиков

У меня сложный вопрос о Neo4j и о том, что может сделать Traversal.

Представьте, что у вас есть следующий график Neo4j

график

Моя идея состоит в том, чтобы пройти весь граф, и если я найду "ложный" узел, разверну этот статус для его соседей и так далее, и, наконец, в этом примере мы получим все узлы со статусом "ложный". (В реальной жизни у меня есть больше условий, чтобы установить этот статус в true или false при обходе, но я немного упростил его для вопроса)

Я думаю, что мне нужен какой-то алгоритм возврата, чтобы сделать это, но в Neo4j я не знаю, как это сделать, или если это вообще возможно. Кроме того, этот график может быть очень огромным графиком.

Как бы вы сделали это с Java и Neo4j?

Благодарю.

2 ответа

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

В Neo4j 3.2.x есть эффективное средство для сопоставления со всеми различными достижимыми узлами посредством сопоставления отношений с переменными плюс использование DISTINCT, но для этого требуется верхняя граница отношения с переменной длиной. Использование достаточно большого числа должно работать. Что-то вроде:

MATCH (:SomeLabel{someProperty:false})-[*..999999]->(x)
WITH distinct x
SET x.someProperty = false

В противном случае процедуры APOC предлагают apoc.path.subgraphNodes(), который также обеспечивает эффективное сопоставление с достижимыми узлами в подграфе:

MATCH (start:SomeLabel{someProperty:false})
CALL apoc.path.subgraphNodes(start, {}) YIELD node
SET node.someProperty = false;

РЕДАКТИРОВАТЬ

Чтобы добавить больше деталей для первого варианта (почему бы просто не использовать * и зачем использовать DISTINCT), имейте в виду, что по умолчанию Cypher будет соответствовать всем возможным путям, когда мы используем *, даже если эти пути заканчиваются на том же узле, что и ранее сопоставленный путь. Это может стать неэффективным в достаточно связанном графе (когда у нас нет разумной верхней границы, и мы не используем LIMIT), с возможностью разорвать вашу кучу или зависать бесконечно.

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

В Neo4j 3.2 была введена оптимизация, называемая pruning-var expand, которая изменяет логику обхода в случае, когда все следующее верно:

  1. У нас есть расширение var-длины
  2. Мы никоим образом не ссылаемся на путь (например, устанавливая переменную пути для шаблона соответствия или устанавливая переменную в отношении var-length)
  3. У нас есть верхняя граница для разложения длины var
  4. Мы просим DISTINCT узлы или значения, полученные из расширения

В основном, когда запрос таков, что ясно, что мы хотим отличные узлы (или значения от разных узлов) от расширения var-length и не заботимся о путях.

Затем планировщик будет использовать сокращение var var (вы можете подтвердить, проверив план запроса из EXPLAIN или PROFILE), чтобы эффективно сопоставить достижимые узлы.

Я не знаю, полностью ли я понял ваш вопрос, но я считаю, что достаточно простого запроса Cypher. Что-то вроде:

MATCH ({someProperty : false})-[*]-(neighbours)
SET neighbours.someProperty = false
Другие вопросы по тегам