Причина, по которой вы не получили ожидаемый результат, заключается в том, что существует путь, соответствующий данному шаблону (узел Node_A
подключен к узлу Node_B
, так что узел Node_B
не подключен к Node_C
узел с label:'A'
). Это потому, что, согласно описанию вашего примера графа, у вас есть 2: Node_B узлы, связанные с вашим единственным: Node_A узлом. Один из них связан с двумя: узлами Node_C, одним из которых является узел: Node_C, которого вы пытаетесь избежать (и в этом случае путь THAT с этим: узел Node_B отфильтровывается из-за вашего предложения WHERE), и другое: узел Node_B подключен к узлу safe: Node_C с меткой 'C', и это путь, который соответствует вашему запросу и возвращается.
Есть несколько способов получить желаемую фильтрацию.
Одним из них является определение полного шаблона, который вы хотите полностью исключить в предложении WHERE, и исключение части: Node_B из предложения MATCH:
MATCH (a:Node_A), (c:Node_C {label:'A'})
WHERE NOT (a) -[:rel_a]-> (:Node_B) -[:rel_b]-> (c)
RETURN a
Если вы не знаете или не заботитесь о промежуточных узлах или отношениях между a
и c
, вы можете опустить их из шаблона:
MATCH (a:Node_A), (c:Node_C {label:'A'})
WHERE NOT (a) --> () --> (c)
RETURN a
Вы можете выразить то же самое, используя отношения переменной длины, где мы знаем, что c
может быть только через 2 прыжка:
MATCH (a:Node_A), (c:Node_C {label:'A'})
WHERE NOT (a) -[*2]-> (c)
RETURN a
EDIT
stdob-- правильно указывает, что для всех этих подходов мы предположили, что в графе существует узел :Node_C
с label:'A'
. Если это не гарантировано, и так получилось, что такого узла НЕТ, то эти запросы ничего не вернут обратно.
Если нам нужно справиться с этим потенциальным случаем, то лучше перенести это из MATCH в предложение WHERE:
MATCH (a:Node_A)
WHERE NOT (a) -[*2]-> (:Node_C {label:'A'})
RETURN a
На самом деле, это, наверное, хорошая вещь в любом случае, так как если бы у нас было несколько таких узлов вместо одного, это могло бы испортить наши результаты, если мы сохраним это в предложении MATCH.