Есть ли способ записи рекурсивных запросов в Cypher? Мне нужно пройти все пути из набора узлов (с меткой L
) в другой набор узлов (m, n, o, ...)
. График направленности и существует несколько путей, какРекурсивный запрос с Cypher на графике Neo4j DB
> (m, n, o, p, ...) -[*]-> ({:L})
рекурсивный запрос должен очертить этот псевдокод
ForEach x where x HasLabel l:
rec(x)
Def rec(node x):
If x in (m, n, o, p):
return
ForEach y where y-->x:
rec(y)
x.prop = f(y.prop, x.prop)
//f(a,b) is a trivial arithmetic function with subtraction and division.
Решение этой потребности не быть рекурсивным один. Любое другое решение будет оценено по достоинству.
EDIT: Перед началом запроса m.prop, n.prop, ..
устанавливаются некоторые значения по мере необходимости. И все остальные узлы (скажем x
) на графике имеют свои x.prop = 0
.
Существует несколько направленных путей, таких как (m,n,o,..)-[*]->({L})
. Для каждого узла x
в этих путях, где (m,n,o,..)-[*]->y-->x-[*]->({:L})
мне нужно, x.prop = x.prop + y.prop.
Это способ размножить свойство от (m,n,o)
к ({:L})
.
Пример:
a-->b-->c-->d:L
^
|
e-->f-->g:L
В начале, a.prop = 1, e.prop = 2
и все другие узлы имеют prop
, как 0
т.е. b.prop = f.prop = c.prop = d.prop = g.prop = 0
Step 1: f.prop = 2
Step 2: b.prop = 1+2 = 3
Step 3: c.prop = 3, g.prop = 2
Step 4: d.prop = 3
Эта процедура легко, когда определена рекурсивно в каждом узле x
как x.prop += (y.prop + z.prop + ...)
, где y-->x, z-->x, ...
Надеюсь, это очистит путаницу.
EDIT: Я написал запрос, используя пути, прежде чем отправлять на StackOverflow. Но может быть логическая ошибка или проблема с циклом foreach. Это может помочь в решении этого вопроса.
MATCH p=((u)-[*]->(v:L{}))
MATCH (x)-[]->(u)
WHERE x.id in ['m','n','o']
FOREACH(n in nodes(p) | set n.marked=x.marked+n.marked)
EDIT: Пойманный проблема с моим запросом. Вышеприведенный запрос правильно задает свойство для узлов в конце, обозначенных как «L». Но, не устанавливает свойство правильно для узлов на пути в сценариях, как этот
c-->d:L
^
|
a-->b-->e:L
Если мой запрос начинается с a.marked=1
, после окончания он устанавливает b.marked=2
. Потому что b
находится в двух путях, ведущих к узлам с меткой «L
». Но, b.marked=1
- ожидаемое значение, поскольку оно связано с узлом, a
через один путь.
Я написал запрос с использованием путей. Но это не сработало, как ожидалось. Может быть и другая логическая ошибка. Вот это его. 'MATCH p = ((u) - [*] -> (v: Kern {})) MATCH (x) - [] -> (u) ГДЕ x.id в ['m', 'n' , 'o'] FOREACH (n в узлах (p) | set n.marked = x.marked + n.marked) ' –
Кстати, ваш запрос не тот, который я ожидал. Я редактировал свой вопрос и добавил некоторые подробности. Надеюсь, теперь я буду ясно. Я также добавил свое решение с путями, которые имеют проблему. Надеюсь, это поможет вам понять мою проблему. –