простой запрос на совпадение с возрастом - PullRequest
0 голосов
/ 04 января 2019

У меня простой запрос

MATCH (n:TYPE {id:123})<-[:CONNECTION*]<-(m:TYPE) RETURN m

и при выполнении запроса «вручную» (т. Е. Используя интерфейс браузера для следования по краям) я получаю в результате только один узел, так как дальнейших подключений нет. Проверка это с помощью запроса

MATCH (n:TYPE {id:123})<-[:CONNECTION]<-(m:TYPE)<-[n:CONNECTION]-(o:TYPE) RETURN m,o

не показывает результатов и

MATCH (n:TYPE {id:123})<-[:CONNECTION]<-(m:TYPE) RETURN m

показывает один узел, поэтому я не ошибся, выполнив запрос вручную.

Однако проблема в том, что первый вопрос занимает много времени, и я не понимаю, почему.

Следовательно : По какой причине такой тривиальный запрос занимает так много времени, хотя максимальный результат равен единице?

Бонус : Как решить эту проблему?

Ответы [ 2 ]

0 голосов
/ 04 января 2019

Как упомянул Tezra, сопоставление с образцом переменной длины не относится к той же категории, что и два других перечисленных вами запроса, потому что нет ограничений, заданных для любого из узлов между n и m, они могут быть любого типа. Учитывая, что ваш запрос занимает много времени, вы, вероятно, имеете довольно плотный график: СВЯЗЬ связей между узлами разных типов.

Если вы хотите убедиться, что все узлы на вашем пути имеют одинаковую метку, вам нужно добавить это самостоятельно:

MATCH path = (n:TYPE {id:123})<-[:CONNECTION*]-(m:TYPE) 
WHERE all(node in nodes(path) WHERE node:TYPE)
RETURN m

В качестве альтернативы вы можете использовать процедуры APOC, которые имеют довольно эффективные средства для поиска подключенных узлов (и ограничения узлов в пути по метке):

MATCH (n:TYPE {id:123})
CALL apoc.path.subgraphNodes(n, {labelFilter:'TYPE', relationshipFilter:'<CONNECTION'}) YIELD node
RETURN node
SKIP 1 // to avoid returning `n`
0 голосов
/ 04 января 2019

MATCH (n:TYPE {id:123})<-[:CONNECTION]<-(m:TYPE)<-[n:CONNECTION]-(o:TYPE) RETURN m,o Неверный тест MATCH (n:TYPE {id:123})<-[:CONNECTION*]<-(m:TYPE) RETURN m, поскольку исключает возможность MATCH (n:TYPE {id:123})<-[:CONNECTION]<-(m:ANYTHING_ELSE)<-[n:CONNECTION]-(o:TYPE) RETURN m,o.

Для вашего основного запроса вы должны возвращать результаты DISTINCT MATCH (n:TYPE {id:123})<-[:CONNECTION*]<-(m:TYPE) RETURN DISTINCT m.

Это по двум основным причинам.

  • Без отдельного, каждому узлу нужно возвращать количество раз для каждого возможного пути к нему.
  • Из-за предыдущего пункта, это много дополнительной работы без дополнительной значимой информации.

Если вы используете RETURN DISTINCT, это дает планировщику шифров возможность выполнить обрезку вместо исчерпывающего поиска.

Вы также можете ограничить глубину исчерпывающего поиска, используя ..#, чтобы он не убивал ваш запрос, если вы запустили более старую версию Neo4j, где Cypher Planner еще не изучил обрезку поиска. Пример использования MATCH (n:TYPE {id:123})<-[:CONNECTION*..10]<-(m:TYPE) RETURN m

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