Я думаю, у вас есть правильная идея: собрать результаты, а затем провести какое-то другое сопоставление, чтобы найти, какой из этих результатов сохранить.Я думаю, что процедуры APOC могут помочь в этом, поскольку его процедуры поиска пути имеют способы остановки при достижении определенных узлов (параметр конфигурации terminatorNodes
).
You 'Я также хочу собирать ваши результаты по пути, чтобы вы не умножали объем работы, которая должна быть выполнена.Например, количество строк для x
из вашего первого совпадения умножит количество раз, когда вы выполняете второе совпадение.Если мы собираем результаты в списки по пути, то мы выполняем каждое раскрытие только один раз, а не мультипликативно для каждой строки (операции Cypher выполняются для каждой строки).Мы можем использовать пересечение списков (из APOC), чтобы получить общие узлы по пути.
Затем мы можем использовать процедуры поиска пути, чтобы найти путь из любого из ваших начальных узлов, с фильтром конечных узлов, таккаждый исследуемый путь останавливается, когда мы достигаем одного из этих общих результатов узлов (которые будут зелеными узлами, которые вы хотите).
Вот пример, который может работать для вас:
MATCH (val0:v {value:"532"} )-[*0..50]->(x:n)
WITH collect(distinct x) as results
MATCH (val1:v {value:"234"} )-[*0..50]->(x:n)
WITH apoc.coll.intersection(results, collect(distinct x)) as results
MATCH (val2:v {value:"678"} )-[*0..50]->(x:n)
WITH apoc.coll.intersection(results, collect(distinct x)) as results
MATCH (start:v {value:"532"} )
CALL apoc.path.subgraphNodes(start, {terminatorNodes:results}) YIELD node as firstCommon
RETURN firstCommon
РЕДАКТИРОВАТЬ
Что касается подхода без APOC, то может сработать что-то подобное, заменив вызов apoc.path.subgraphNodes()
:
...
MATCH p=(start:Root {id:532} )-[*0..50]->(x)
WHERE x in results and single(node in nodes(p) where node in results)
RETURN distinct x