2015-10-22 4 views
1

Есть ли способ записи рекурсивных запросов в 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 через один путь.

ответ

0

Я не уверен на 100%, что я поступаю правильно. Может быть полезно описание того, что вы пытаетесь сделать на английском.Тем не менее, вот удар у него:

MATCH path=(start)-[*0..5]-(:L) 
WHERE start.prop > 0 
WITH nodes(path)[-2] AS x, y 
SET y.prop = (y.prop + x.prop) 

Потому что мы делаем переменную спичку пути, path найдет каждый путь от l к каждому узлу, подключенному к нему во входящем порядке. Мы не включаем значения y, которые указаны в нашем списке исключений. Затем для каждого найденного path мы берем второе и последнее (x) и последнее (y) и делаем наши расчеты и наш SET.

Надеюсь, это полезно!

EDIT: Из ваших примеров кажется, что вы хотите совпадать с отношениями независимо от направления (казалось, вы просто хотели сопоставить пути, входящие в стартовую точку). Я удаляю меньше (<), так что путь соответствует двунаправленно. Я также внесли некоторые другие изменения, теперь я лучше понимаю проблему, и я думаю, что это может помочь.

Также имейте в виду, что я добавил ограничение на размер переменной пути. Вы можете настроить это, чтобы быть больше (или вообще не ограничено) в зависимости от размера/топологии вашего графика. Также обратите внимание, что -[*]- соответствует (я думаю) от пути длины один до бесконечной длины пути. Поэтому, если вы адаптируете мое решение, вы, вероятно, захотите использовать -[0..], потому что опция нулевой длины пути соответствует ей.

+0

Я написал запрос с использованием путей. Но это не сработало, как ожидалось. Может быть и другая логическая ошибка. Вот это его. 'MATCH p = ((u) - [*] -> (v: Kern {})) MATCH (x) - [] -> (u) ГДЕ x.id в ['m', 'n' , 'o'] FOREACH (n в узлах (p) | set n.marked = x.marked + n.marked) ' –

+0

Кстати, ваш запрос не тот, который я ожидал. Я редактировал свой вопрос и добавил некоторые подробности. Надеюсь, теперь я буду ясно. Я также добавил свое решение с путями, которые имеют проблему. Надеюсь, это поможет вам понять мою проблему. –

Смежные вопросы