Как запросить уровни Neo4j N в глубину с отношением переменной длины и фильтрами на каждом уровне - PullRequest
0 голосов
/ 11 июля 2019

Я новичок в Neo4j и пытаюсь создать инструмент, позволяющий пользователям в пользовательском интерфейсе по существу указывать путь узлов, для которых они хотели бы запросить neo4j.Для каждого узла в пути они могут указывать конкретные свойства узла, и, как правило, им нет дела до типов / свойств отношений.Отношения должны быть переменными по длине, потому что типичный вариант использования для них - у них есть начальный узел, и они хотят знать, достигает ли он некоторого конечного узла, не заботясь о (всех) промежуточных узлах между началом и концом.

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

Проблема, с которой я сталкиваюсь, заключается в возможности указать фильтрацию на каждом уровне пути без странного поведения.

Я пробовал множество вариантов моего запроса Cypher, таких как взломна пути к множественным операторам MATCH, играющим с отношениями и всем остальным, о чем я мог подумать.

Вот список примеров дампа Cypher cypher-dump

Этот запрос дает мне путь, который я пытаюсь получить, но не указывает имяили введите n_four.

    MATCH path = (n_one)-[*0..]->(n_two)-[*0..]->(n_three)-[*0..]->(n_four)
    WHERE n_one.type IN ["JCL_JOB"]
    AND n_two.type IN ["JCL_PROC"]
    AND n_three.name IN ["INPA", "OUTA", "PRGA"]
    AND n_three.type IN ["RESOURCE_FILE", "COBOL_PROGRAM"]
    RETURN path

CorrectGraph

Этот запрос - то, что я хотел бы обработать, однако он оставляет на третьем уровне листья, которые мне трудно понять.

    MATCH path = (n_one)-[*0..]->(n_two)-[*0..]->(n_three)-[*0..]->(n_four)
    WHERE n_one.type IN ["JCL_JOB"]
    AND n_two.type IN ["JCL_PROC"]
    AND n_three.name IN ["INPA", "OUTA", "PRGA"]
    AND n_three.type IN ["RESOURCE_FILE", "COBOL_PROGRAM"]
    AND n_four.name IN ["TAB1", "TAB2", "COPYA"]
    AND n_four.type IN ["RESOURCE_TABLE", "COBOL_COPYBOOK"]
    RETURN path

IncorrectGraph

Что я заметил, так это то, что когда я "... RETURN n_four" в моем запросе, он включает в себя также узлы, которые находятся на третьем уровне.

1 Ответ

1 голос
/ 19 июля 2019

Это вызвано тем, что вы (вероятно, неуместно) используете [*0..] в своем шаблоне MATCH.

К вашему сведению:

  • [*0..] соответствует 0или больше отношений.Например, (a)-[*0..]->(b) будет успешным, даже если a и b - это один и тот же узел (и нет связи между этим узлом и самим собой).

  • Нижний уровень по умолчаниюпредел равен 1. Таким образом, [*] эквивалентно [*..] и [*1..].

Ваши два запроса используют один и тот же шаблон MATCH, заканчивающийся ...->(n_three)-[*0..]->(n_four).

  • Ваш первый запрос не указывает WHERE тестов для n_four, поэтому запрос может свободно возвращать пути, в которых n_three и n_four являются тем же самым узлом .Это отсутствие специфичности является причиной того, что запрос может вернуть 2 дополнительных узла.

  • Ваш второй запрос указывает WHERE тесты для n_four, которые делают невозможным для n_three и n_four быть тем же узлом.Запрос теперь более разборчивый, и поэтому эти 2 дополнительных узла больше не возвращаются.

Не следует использовать [*0..], если вы не уверены, что хотите опционально сопоставить 0 отношений.Это также может добавить ненужные накладные расходы.И, как вы теперь знаете, это также усложняет понимание запроса.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...