2017-02-08 1 views
2

У меня есть узел, скажем, человек, которому принадлежат узлы. Я хочу получить все узлы, принадлежащие этому человеку, которые не являются дочерними узлами, принадлежащими этому лицу. Кроме того, ребенок может быть на несколько уровней глубоким (то есть, если A является дочерним по B, а B является дочерним по C, то A является дочерним по C).Из набора узлов, получить все узлы в наборе, которые не являются дочерними узлами в этом наборе

Например, если мы имеем

A <-[:CHILD_OF]- B <-[:CHILD_OF]- C   E <-[:CHILD_OF]- F 
^
    | 
[:CHILD_OF] 
    | 
    D 

и человек владеет A, F, D и C, тогда только и F должен вернуться, потому что D является потомком A и C является потомком A

Вот как я сейчас делаю это:

MATCH (person)-[:OWNS]->(owned) WITH COLLECT(DISTINCT owned) AS owned 
RETURN FILTER(x in owned WHERE ALL (y in owned WHERE NOT ((x)-[:CHILD_OF*..20]->(y)))) AS children 

Но если ребенок более чем 20 уровней в глубину, этот запрос будет возвращать. Я мог бы использовать [: CHILD_OF *] для соответствия бесконечному количеству отношений [: CHILD_OF], но это может замедлить работу, если у меня много уровней узлов. Есть ли лучший запрос для этого?

ответ

2

Вы можете попробовать использовать функцию shortestPath:

MATCH (person)-[:OWNS]->(owned) WITH COLLECT(DISTINCT owned) AS owned 
FILTER(x IN owned WHERE ALL (
    y IN owned WHERE NOT CASE WHEN shortestPath((x)-[:CHILD_OF*]->(y)) IS NULL 
           THEN TRUE 
           ELSE FALSE 
         END 
)) AS children 
Смежные вопросы