2015-03-27 2 views
3

У меня есть схема, где узлы связаны двумя типами отношений - r: A и r: B. Я пытаюсь написать шаблон, который будет найти все пути от узла к узлу N M. Это может быть просто сделано следующим Cypher запрос:Neo4j Cypher traversal - найти путь по нескольким типам отношений

match path = (n)-[:A|:B*]->(m) return path; 

К сожалению, это не то, что мне нужно точно. Мне нужно найти каждый путь от (n) до (m), где глубина через отношение r: A может быть бесконечной, но по пути может использоваться только ограниченное число отношений r: B. В сценарии счастливого дня запрос cypher будет выглядеть так:

match path = (n)-[:A*|:B*0..3]->(m) return path; 

Однако cypher не позволяет использовать этот синтаксис. Я не могу решить эту проблему, даже с использованием другого «помогает» узел на пути:

match path = (n)-[:A*]->()-[:B*0..3]->(m) return path; 

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

(n)-[r:A]-()-[r:A]-()-[r:A]-(m) 
(n)-[r:A]-(m) 
(n)-[r:A]-()-[r:B]-()-[r:A]-()-[r:B]-()-[r:A]-()-[r:A]-(m) 

Есть ли способ, как это можно достичь? Если не в cypher, может ли это быть сделано в gremlin/neo4j traversal api/embedded функции проекта spring neo4j?

Спасибо за ответы.

ответ

1

Попробуйте это:

СПИЧКА путь = (п) - [: A |: B *] -> (м)
с пути, отношения (пути) при г, фильтр (отн в отношения (путь)
где тип (отн) = 'В') КАК Brels
с пути, уменьшают (Bcount = 0, отн В Brels | Bcount + 1) КАК Bcount
WHERE Bcount < = 3
путь возврата

Я не знаю, полностью ли я понял вопрос. Просто дай мне знать.

EDIT:
Я добавил второй запрос после комментариев. Это решение является уродливым, но оно является хорошим обходным решением.

СПИЧКА путь = (п) - [: A |: B *] - (м)
с пути, фильтр (отн в отношений (путь) где тип (REL) = 'В') А.С. Brels
с пути, уменьшают (Bcount = 0, отн В Brels | Bcount + 1) КАК Bcount
ГДЕ Bcount < = 3
с пути, отношения (путь) AS RELS
с пути, RELS, уменьшить (count = 0, rel IN rels | count + 1) AS count
WI TH путь, rels, диапазон (0, счет-1) в качестве счетчика
С помощью пути, уменьшить (x = 0, c IN counter |
случай, когда (типа (RELS [с]) = 'В' и тип (RELS [с + 1]) = 'В') ТОГДА х + 200000 ИНАЧЕ х + 1 КОНЕЦ) КАК CountX
ГДЕ CountX RETURN path, countX

+1

Да, это отвечает на мой вопрос - спасибо большое. К сожалению, если я не ошибаюсь, алгоритм, во-первых, найдет все возможные пути (даже пути, где используются более 3 отношений r: B) и затем фильтровать результаты? Я был бы признателен, если бы поиск не пошел даже по пути с более чем тремя отношениями r: B. Кроме того, можно ли сказать, что я хочу использовать только одно отношение r: B за раз? - Это означает, что (n) - [: B] -() - [: B] - (m) не является результатом, которого я хочу, потому что путь следует за двумя: B отношениями последовательно. Другими словами - если использовалось отношение r: B, следующее отношение ДОЛЖНО быть r: A. –

+0

Кубо, да, алгоритм - не лучшее решение. Боюсь, вам понадобится другой метод запроса, чем Cypher, потому что ваши сценарии сложны, но вы упомянули в вопросе. Я добавлю второй запрос cypher к ответу, который может вам помочь. –

+0

@JakubChalupa: Я забыл упомянуть ваше имя пользователя в комментарии. Я исправлю это здесь. –