2016-12-10 7 views
1

Я хочу вернуть все узлы и б, где б не ниже по потоку от в через любой путь, который начинается с соотношением отн , Я продолжаю находить себе того, чтобы написать одно условие для случая, когда связана непосредственно с б через отн, и один для непрямого случае, что приводит к чему-то вроде этого:Шифр: Количественная над ноль или более узлов-то-отношения

//Semi-pseudo-code. 
match   (a)-[*]->(b) 
optional match dir=(a)-[:rel]->(b) 
optional match indir=(a)-[:rel]-()-[*]->(b) 
where   length(dir)=0 
and    length(indir)=0 
return   a,b 

Есть любой более простой способ? На самом деле я хочу что-то вроде этого, где голые квантор означает «ноль или более узлов-то-отношения»:

match   (a)-[*]->(b) 
match not  (a)-[:rel]-*->(b) 
return   a,b 

Примечание: Я подозреваю, что это может в корне быть такой же, как мой последний вопрос: Cypher: Matching nodes at arbitrary depth via a strictly alternating set of relations

ответ

2

Мы можем использовать WHERE NOT формулировать отрицательные условия, аналогичным образом на свой второй полуфинал псевдокоде:

MATCH  (a)-[*]->(b) 
WHERE NOT ((a)-[:rel]->()-[*1..]->(b)) 
RETURN a, b 

конечно, это будет что-нибудь, но эффективным, так что вы должны, по крайней мере, попытаться ограничить метки a и b и взаимосвязи между ними, например. (a:Label1)-[:rel1|rel2*]->(b:Label2)

Пример:

CREATE 
    (n1:N {name: "n1"}), 
    (n2:N {name: "n2"}), 
    (n3:N {name: "n3"}), 
    (n4:N {name: "n4"}), 
    (n5:N {name: "n5"}), 
    (n1)-[:x]->(n2), 
    (n3)-[:rel]->(n4), 
    (n4)-[:x]->(n5) 

enter image description here

Результаты запроса в:

╒══════════╤══════════╕ 
│a   │b   │ 
╞══════════╪══════════╡ 
│{name: n1}│{name: n2}│ 
├──────────┼──────────┤ 
│{name: n4}│{name: n5}│ 
└──────────┴──────────┘ 

Как вы можете видеть, это не включает в себя n3 и n5, как она начинается с :rel отношений.

+0

Благодарим за ответ. Но не будет ли ваш код по-прежнему соответствовать прямому делу ?: (a) - [: rel] -> (b) Мне нужно исключить это. (Или я неправильно понял?) –

+0

Хорошая точка - [отношения переменной длины] (https://neo4j.com/docs/developer-manual/current/cypher/#_variable_length_relationships) по умолчанию значение 'minHops' равно 1. Я исправил запрос и добавит пример через минуту. –

1

Это должно работать:

MATCH (a)-[rs*]->(b) 
WHERE TYPE(rs[0]) <> 'rel' 
RETURN a, b; 

Однако ниже запрос должен быть гораздо более производительным, так как он фильтрует все нежелательные пути начала до того это делает очень дорогой переменной длины пути поиска. Синтаксис *0.. делает поиск по длине переменной длины нижней границей 0 для длины (так что x также будет возвращен как b).

MATCH (a)-[r]->(x) 
WHERE TYPE(r) <> 'rel' 
MATCH (x)-[*0..]->(b) 
RETURN a, b;