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
Другие вопросы по тегам