Как получить все узлы в несвязном подграфе - neo4j / py2neo

Если у меня есть база данных neo4j, и я хочу запросить, чтобы получить все узлы, которые находятся в одном конкретном несвязном подграфе. (в py2neo или в cypher)

Если у меня есть группы узлов, узлы в каждой группе связаны отношениями внутри этой группы, но не связаны между группами. Могу ли я запросить один узел и получить все узлы в группе этого узла?

2 ответа

Решение

[ОБНОВЛЕНО]

Оригинальный ответ

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

MATCH (n { name: "Neo" })
OPTIONAL MATCH p=(n)-[*]-(m)
RETURN REDUCE(s = [n], x IN COLLECT(NODES(p)) |
  REDUCE(t = s, y IN x | CASE WHEN y IN t THEN t ELSE t + y END )) AS nodes;

Этот запрос использует OPTIONAL MATCH чтобы найти узлы, "связанные" с Neo узел, так что если этот узел не имеет отношений, запрос все равно сможет вернуть результат.

Два (вложенные) REDUCE предложения гарантируют, что возвращаемая коллекция имеет только отдельные узлы.

Внешний REDUCE предложение инициализирует коллекцию результатов с n узел, так как он всегда должен находиться в непересекающемся подграфе, даже если нет других узлов.

Лучший ответ

MATCH p=(n { name: "Neo" })-[r*0..]-(m)
WITH NODES(p) AS nodes
UNWIND nodes AS node
RETURN DISTINCT node

Этот более простой запрос (который возвращает строки узлов) использует [r*0..] разрешить пути 0 длины (т.е. n не нужно иметь никаких отношений - и m может быть таким же, как n). Оно использует UNWIND повернуть nodes сборка узлов в строки, а затем использует DISTINCT устранить дубликаты.

Альтернативное решение (пока не работает из-за ошибки)

Это альтернативное решение ниже (которое возвращает строки узлов) также должно сработать, за исключением того, что в настоящее время существует ошибка ( о которой я только что сообщил), которая приводит к тому, что все идентификаторы забываются после того, как запрос раскручивает NULL (что может произойти, например, если OPTIONAL MATCH не может найти совпадение). Из-за этой ошибки, если Neo узел не имеет отношений, запрос ниже в настоящее время не возвращает результатов. Поэтому вы должны использовать запрос выше, пока ошибка не будет исправлена.

MATCH (n { name: "Neo" })
OPTIONAL MATCH p=(n)-[*]-(m)
WITH n, NODES(p) AS nodes
UNWIND nodes AS node
RETURN DISTINCT (
  CASE
  WHEN node IS NULL THEN n
  ELSE node END ) AS res;

Это может помочь, если вы добавили диаграмму или некоторые примеры данных. Однако, если я правильно понимаю вашу модель данных, вы определяете "группы" узлов как все узлы, связанные определенным отношением? Таким образом, чтобы получить всех членов узлов "group1" (давайте определим, что это все узлы, связанные отношением group1), а не какие-либо узлы, связанные с group2, вы можете использовать такой запрос:

MATCH (a:Person)-[:GROUP1]-(b:Person)
WHERE NOT exists((a)-[:GROUP2]-())
RETURN a

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

Другие вопросы по тегам