Как получить все связанные узлы, исключая определенные отношения - PullRequest
0 голосов
/ 30 ноября 2018

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

Прикрепленный рисунок иллюстрирует мой случай.

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

Я знаю, как извлечь все подключенные узлы с помощью:

MATCH (n:MyNode {id : 123})-[*]-(connectedNodes) RETURN connectedNodes

Фильтрация с предложением WHERE звучит как плохая идея, потому что она все равно будет извлекатьвесь график.Есть ли что-то внутри процедур APOC, что позволило бы мне что-то сделать таким образом?Большое спасибо уже за вашу помощь.

РЕДАКТИРОВАТЬ 1: Софар Я попробовал первое предложение, данное в комментариях, но время выполнения было недостаточно.Я постараюсь ограничить отношения и типы узлов.Также я попробовал пользовательскую реализацию внутри Python, используя рекурсивную функцию.Пока еще не завершено.

РЕДАКТИРОВАТЬ 2: Предложение @ InverseFalcon сработало как очарование.Сначала отфильтруйте все доступные типы отношений за один раз, которые не должны учитываться, а затем примените процедуру apoc.path.subgraphNodes с соответствующим начальным узлом и действительными типами отношений.Спасибо.enter image description here

Ответы [ 2 ]

0 голосов
/ 30 ноября 2018

Ответ Тезры имеет несколько положительных моментов, и вы захотите вернуть DISTINCT connectedNodes, в противном случае вы получите дубликаты, но на графике с высокой степенью связи это может занять некоторое время (или даже зависание) в зависимости от количества узлов, поскольку Cypherинтересуется всеми возможными путями для совпадений, и это может быстро выйти из-под контроля.

Для APOC мы можем справиться с этим случаем, но, как заметил Тезра, у нас нет способа занести в черный список отношения, и даже еслиу нас это было, у нас нет способа занести черный список на основе частичных имен типов отношений.

Подход, который вам нужно будет использовать, - сначала получить все типы отношений, а затем удалить все типы, начинающиеся с * 1005.*, затем объедините список оставшихся отношений в | отдельную строку.Тогда вы могли бы передать это фильтру отношений.

CALL db.relationshipTypes() YIELD relationshipType
WHERE NOT relationshipType STARTS WITH 'LINK'
WITH collect(relationshipType) as relTypes
WITH apoc.text.join(relTypes, '|') as relTypesString
MATCH (n:MyNode {id : 123})
CALL apoc.path.subgraphNodes(n, {relationshipFilter:relTypesString}) YIELD node
RETURN node as connectedNode
0 голосов
/ 30 ноября 2018

Во-первых, я хочу подчеркнуть, что Cypher не ограничивает способ получения информации, он только определяет, что возвращается.Поэтому попробуйте использовать WHERE перед тем, как исключить его (также попробуйте обновить его до последней версии Neo4j для самого умного планировщика шифров).Это должно работать просто отлично, потому что планировщик шифров может фильтровать результаты, пока они совпадают.

MATCH (n:MyNode {id : 123})-[rs*]-(connectedNodes)
WHERE NONE(r in rs WHERE TYPE(r)="LINK")
RETURN DISTINCT connectedNodes

Процедуры APOC , о которых я могу подумать, требуют, чтобы вы назвали используемые отношения (вы можетеметки черного списка, но, похоже, не относятся к типам отношений), поэтому будут такими же, как -[rs:A|B|C|D*]-

...