Как получить все узлы в несвязном подграфе - 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
Вы также можете использовать метки узлов для определения групп узлов.