ТЛ; ДР
В Cypher невозможны бесконечные циклы, и такие циклы на вашем графике не только создают проблему для производительности запросов.
Длинный подробный ответ
Это большой вопрос, и начало ответа находится в документации уникальность в обходах Cypher :
При сопоставлении с шаблоном Neo4j не учитывает совпадения, в которых одно и то же отношение графика встречается несколько раз в одном шаблоне. В большинстве случаев это разумно.
Хотя было бы точнее сказать:
, где одно и то же графическое отношение встречается несколько раз в одном пути
Поскольку пути проходят в соответствии с шаблоном совпадения, определенные отношения могут быть пройдены только один раз в этом пути. Направление обхода здесь не имеет значения. Не имеет значения, имеет ли отношение присвоенную ему переменную или является ли отношение частью пути переменной длины. Как только отношения пройдены по одному пути, они никогда не пройдут снова.
Это в значительной степени защищает вас от бесконечных циклов, которые по определению требуют, чтобы вы пересекали одни и те же отношения снова и снова.
Однако это не защищает вас от возрастания затрат, когда между узлами очень много множественных путей из-за перестановки всех возможных отношений (все уникальные и никогда не повторяющиеся для пути), которые могут быть пройдены.
Например, если вы берете граф Movies из :play movies
в браузере Neo4j, вы можете выполнить запрос, подобный MATCH (n:Person)-[*]-(m:Person) RETURN count(*)
, и он, вероятно, никогда не вернется, как число возможных путей между любыми двумя: узлами Person, из-за перестановки всех возможных отношений, которые могут быть пройдены (не повторяя их в каждом отдельном пути), становится чрезмерно дорогостоящим (и это делается для всех возможных комбинаций двух: узловых лиц в графе).
Этот тип запроса в конечном итоге заблокирует Neo4j, поскольку количество путей для оценки становится астрономическим, но опять-таки это не из-за бесконечных циклов.
Чтобы обойти эти виды ограничений (в конце концов, вы можете захотеть использовать очень похожий запрос, чтобы найти отдельные достижимые узлы, или число достижимых отдельных узлов), вам нужно будет изменить уникальность обхода по сравнению с Cypher ' RELATIONSHIP_PATH 'уникальность к чему-то еще.
Если вы используете Traversal Framework в Java (которую вы можете использовать, если вы создаете пользовательскую процедуру, расширение ядра или используете встроенный Neo4j), вы можете изменить уникальность обхода на другое поведение.
Что касается избежания бесконечных циклов, уникальность 'NODE_PATH' также будет предотвращать их, так как это гарантирует, что узел может быть посещен только один раз для отдельного пути.
Одной из наиболее полезных, которые также предотвращают бесконечные циклы, является уникальность 'NODE_GLOBAL', которая обеспечивает посещение узла только один раз всего по всем путям , а не только по каждому пути. Именно эту уникальность лучше всего использовать, когда вы хотите найти все отдельные узлы (или подсчитать все отдельные узлы), достижимые из начального узла, и поэтому мы используем уникальность 'NODE_GLOBAL' в пределах определенных процедур расширения пути из библиотеки APOC Процедуры (а при использовании apoc.path.expandConfig()
вы можете явно установить уникальность самостоятельно, если вы хотите другой тип).
Итак, в итоге, по умолчанию бесконечные циклы не могут происходить с использованием Cypher.Некоторые из более серьезных проблем с производительностью Cypher, с которыми вы сталкиваетесь, могут быть связаны со стремительно растущим числом возможных путей, совпадающих с шаблоном соответствия, особенно с неограниченным расширением переменной длины, поскольку это может поглотить пространство кучи или иным образом превратиться в чрезвычайно большое числоуникальных путей для оценки.С помощью процедур обхода API или APOC вы можете изменить поведение уникальности обхода в соответствии с потребностями вашего запроса.