Cypher Query, где 2 разные метки не содержат отношения к третьей метке / узлу
У меня есть 3 метки, A, B и Z. Обе A и B имеют отношение к Z. Я хочу найти все узлы A, которые не имеют общих узлов Z, общих с B
В настоящее время работает нормальный запрос, где связь существует, работает.
MATCH (a:A)-[:rel1]->(z:Z)<-[:rel2]-(b:B { uuid: {<SOME ID>} })
RETURN DISTINCT a
Но, когда я делаю
MATCH (a:A)
WHERE NOT (a)-[:rel1]->(z:Z)<-[:rel2]-(b:B { uuid: {<SOME ID>} }))
RETURN DISTINCT a
Выдает ошибку
Neo4j::Server::CypherResponse::ResponseError: z not defined
Не уверен, что синтаксис для этого неверен, я пытался WHERE NOT EXIST()
но не повезло.
Запрос является частью большего запроса, вызываемого через приложение rails с использованием neo4jrb / (Neo4j::Session.query)
2 ответа
Это проблема, связанная с объемом вашего запроса. Когда вы описываете узел в MATCH
пункт как ниже
MATCH (n:SomeLabel)
Вы говорите Cypher искать узел с меткой SomeLabel
и назначьте его переменной n
в остальной части запроса и в конце запроса вы можете вернуть значения, хранящиеся в этом узле, используя RETURN n
(если вы не уроните n
не включая его в WITH
пункт).
Позже в вашем запросе, если вы хотите MATCH
другой узел, вы можете сделать это со ссылкой на n
так, например:
MATCH (m:SomeOtherLabel)-[:SOME_RELATIONSHIP]-(n)
Будет соответствовать переменной, связанной (в любом направлении) с узлом n
с этикеткой SomeOtherLabel
и назначьте его переменной m
для остальной части запроса.
Вы можете назначать узлы только таким переменным в MATCH
, OPTIONAL MATCH
, MERGE
, CREATE
и (вроде) в WITH
а также UNWIND
пункты (кто-то исправляет меня здесь, если я пропустил один, я полагаю, вы также делаете это в списках и FOREACH
положения).
Во втором запросе вы пытаетесь найти узел с меткой A
, который не связан с узлом с меткой Z
, Однако то, как вы написали запрос, означает, что вы на самом деле говорите: найдите узел с меткой A
который не связан через rel1
отношение к узлу хранится как z
, Это не удастся (и, как показано, нео жалуется, что z
не определяется), потому что вы не можете создать новую переменную, как это в WHERE
пункт.
Чтобы исправить ошибку, вам нужно удалить ссылку на переменную z
и убедитесь, что вы также определили переменную b
содержащий ваш узел до WHERE
пункт. Теперь вы сохраняете метку в запросе, как показано ниже.
MATCH (a:A)
MATCH (b:B { uuid: {<SOME ID>} })
WHERE NOT (a)-[:rel1]->(:Z)<-[:rel2]-(b) // changed this line
RETURN DISTINCT a
И если повезет, теперь это сработает.
Вы получаете ошибку, потому что z - это идентификатор узла, который вы используете в предложении where, которое вы еще не определили.
Поскольку вы уже знаете b, я сначала сопоставлю его, а затем использую в предложении where. Вам не нужно назначать :Z
достаточно идентификатора, просто используя метку узла.
MATCH (b:B { uuid: {<SOME ID>} })
WITH b
MATCH (a:A)
WHERE NOT (a)-[:rel1]->(:Z)<-[:rel2]-(b)
RETURN DISTINCT a