1.
shorttestPath () может помочь, когда ваши уже совпавшие начальные и конечные узлы не являются корневыми и конечными, поскольку они не будутпродолжайте искать дополнительные пути, как только найден первый.Если ваши уже совпадающие начальные и конечные узлы являются корневым и конечным узлом, когда граф представляет собой древовидную структуру (ациклическая), то нет реальной причины использовать shorttestPath ().
Обычно при установкечто-то вроде глубины узла в дереве, вы должны использовать length(path)
, поэтому корень будет на глубине 0, а его дочерние элементы - на глубине 1.
Обычно глубина рассчитывается относительно корневого узла ине листовые узлы (поскольку промежуточный узел может быть предком множества листовых узлов на разных расстояниях).Использование глубины в качестве расстояния от корня делает глубины согласованными.
Ваш подход с установкой свойства для отношений будет проблемой, так как одни и те же отношения могут присутствовать в нескольких путях для нескольких конечных узлов на различной глубине.,Ваш запрос может перезаписывать свойство одних и тех же отношений снова и снова, пока не победит последняя запись.Было бы лучше сопоставить все узлы (пропустить :Leaf
в запросе), взять последнее отношение в пути и установить его глубину:
MATCH path=(:Parent {Parent_ID: $known_value})<-[:R*]-()
WITH length(path) as length, last(relationships(path)) as rel
SET rel.Level = length
2.
Итак, если все дочерние узлы родителя в дереве: как в фильме, тогда родитель должен: как в фильме.Примерно так должно работать:
MATCH path=(:Parent {Parent_ID: $known_value})<-[:R*0..]-(n)
WITH n, size((n)<-[:R]-()) as childCount
MATCH (n)<-[:R]-()-[:like]->(m:Movie)
WITH n, childCount, m, count(m) as movieLikes
WHERE childCount = movieLikes
MERGE (n)-[:like]->(m)
Идея здесь в том, что для фильма, если количество узлов этого фильма равно количеству дочерних узлов, тогда всем детям понравился фильм (при условии, чтоузел может только: как один и тот же фильм один раз).
Этот запрос не может быть использован для создания лайков снизу вверх, однако, подобные отношения (симпатия лично, а не симпатия, потому что она понравилась всем детям)) сначала должен присутствовать на всех узлах, чтобы этот запрос работал.
3.
Чтобы выполнить восходящий подход, вам необходимопринудительно выполнить запрос в определенном порядке, и я считаю, что лучший способ сделать это - сначала упорядочить узлы для обработки в глубоком порядке, а затем использовать apoc.cypher.doIt () , процесс в Процедуры APOC , которые позволяют выполнить весь запрос Cypher для каждой строки, чтобы выполнить вычисление.
Этот подход должен работать:
MATCH path=(:Parent {Parent_ID: $known_value})<-[:R*0..]-(n)
WHERE NOT n:Leaf // leaves should have :like relationships already created
WITH n, length(path) as depth, size((n)<-[:R]-()) as childCount
ORDER BY depth DESC
CALL apoc.cypher.doIt("
MATCH (n)<-[:R]-()-[:like]->(m:Movie)
WITH n, childCount, m, count(m) as movieLikes
WHERE childCount = movieLikes
MERGE (n)-[:like]->(m)
RETURN count(m) as relsCreated",
{n:n, childCount:childCount}) YIELD value
RETURN sum(value.relsCreated) as relsCreated
Тем не менее, яне уверен, что это будет делать то, что вы тХинк это подойдет.Или, скорее, он будет работать так, как вы думаете, только если: единственные отношения с фильмами изначально устанавливаются только на конечных узлах, и (до запуска этого запроса на распространение) ни один другой промежуточный узел в дереве не имеет: likeотношение к фильму.