NEO4j Cypher-запрос для возврата путей с условием на количество подключенных узлов - PullRequest
0 голосов
/ 30 ноября 2018

Я бы хотел немного очистить базу данных графов, удалив ненужные узлы.В одном случае ненужными узлами являются узлы B между узлами A и C, где B имеет то же имя, что и узел C, и НИКАКИХ ДРУГИХ входящих связей.У меня возникают проблемы при создании запроса Cypher, который ограничивает количество входящих ребер.

Первая часть была простой:

MATCH (n1:TypeA)<-[r1:Inside]-(n2:TypeB)<-[r2:Inside]-(n3:TypeC)
WHERE n2.name = n3.name

Основано на других вопросах SE (особенно этоone ) Затем я попытался сделать что-то вроде:

WITH n2, collect(r2) as rr
WHERE length(rr) = 1 
RETURN n2

, но это также вернуло узлы с более чем одним входящим фронтом.Кажется, мое предложение WHERE по длине не фильтрует возвращенные узлы n2.Я попробовал несколько других вещей, которые я нашел в Интернете, но они либо ничего не возвращали, либо не были синтаксически правильными в текущей версии.

После того, как я найду n2 узлы, которые соответствуют шаблону, я хочу подключить n3 напрямую к n1 и DETACH DELETE n2.Опять же, я легко смог выполнить эту часть, когда мне не нужно было ограничивать число входящих ребер до n2.Этот предыдущий вопрос имеет FOREACH (r IN rr | DELETE r), но я хочу отменить удаление n2 узлов, а не только этих ребер.Я не знаю, как правильно адаптировать это для работы на узлах, подключенных к r s, и я, конечно, хочу быть уверен, что он находит правильные узлы перед удалением чего-либо, так как в Neo4j отсутствует базовая функциональность отмены (но вы не можете поставитькоманда RETURN внутри FOREACH по какой-то безумной причине).

Как отфильтровать узлы на пути по количеству входящих ребер с помощью Cypher?

Я думаю, что я могу сделать это в py2neo, сначала собрав все n1,n2,n3 тройки, соответствующие шаблону, затем пройдя каждую возвращенную запись и добавив их в список, если n2 имеет только один входящий фронт.Затем просмотрите этот список и выполните операцию обрезки, но если это можно сделать в чистом Cypher, то я хотел бы знать, как, потому что у меня есть ряд аналогичных настроек.

Ответы [ 2 ]

0 голосов
/ 30 ноября 2018

Вы должны указать path в вашем WITH утверждении.

MATCH path = (n1:Ward)<-[r1:PARTOF]-(n2:Unknown)<-[r2:PARTOF]-(n3:Chome)
WHERE n2.name = n3.name
WITH path, size((n2)<-[:PARTOF]-()) as degree
WHERE degree = 1
RETURN path

Или, короче, как это:

MATCH path = (n1:Ward)<-[r1:PARTOF]-(n2:Unknown)<-[r2:PARTOF]-(n3:Chome)
WHERE n2.name = n3.name
AND size((n2)<-[:PARTOF]-()) = 1
RETURN path
0 голосов
/ 30 ноября 2018

Заимствуя некоторую информацию из этого ответа Я пришел к выводу, что, кажется, работает.

MATCH path = (n1:Ward)<-[r1:PARTOF]-(n2:Unknown)<-[r2:PARTOF]-(n3:Chome)
WHERE n2.name = n3.name
WITH n2, size((n2)<-[:PARTOF]-()) as degree
WHERE degree = 1
MATCH (n1:Ward)<-[r1:PARTOF]-(n2:Unknown)<-[r2:PARTOF]-(n3:Chome)
RETURN n1,n2,n3

Я ожидаю, что не все его части необходимы, и это не такэффективное решение, но я еще не знаю достаточно, чтобы улучшить его.

Например, я определяю первую строку как path, но я не могу использовать MATCH path в предпоследней строке,и я понятия не имею, почему.

Кроме того, если я напишу WITH size((n2)<-[:PARTOF]-()) as degree (отбрасывая n2, после WITH), он возвращает не только n2 со степенью> 1, но также и все узлы, связанные с ними (даже больше, чем n3 узлов).Я не знаю, почему он так себя ведет, и документация Neo4j для WITH не имеет примеров или описания, чтобы помочь мне понять, почему n2 здесь необходим.Будем весьма благодарны за любые улучшения в моем запросе Cypher или объяснение как или почему работает

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...