Neo4j - кратчайший путь через узел - PullRequest
0 голосов
/ 24 октября 2018

Я пытаюсь получить кратчайший путь между узлом (a) и узлом (c) через определенный узел (b) с меткой SomeImportantLabel.Нарисовано, это то, что я хочу:

(a)-(?..)-(b:SomeImportantLabel)-(?..)-(c)

Обратите внимание, что (?..) означает, что между ними может быть 'n' количество узлов.

Примерно так будет сделка Iищу:

match p = allShortestPaths((a)-[*]-(b:SomeImportantLabel)-[*]-(c)) 
where id(a) = 123 and id(c) = 456 
return nodes(p) as nodes, relationships(p) as rels;

Так как в функции shortestPath / allShortestPaths невозможно иметь несколько отношений, я прочитал здесь на SO, что вам придется делать это таким образом:

match p1 = allShortestPaths((a)-[*]-(b:SomeImportantLabel)), p2=allShortestPaths((b:SomeImportantLabel)-[*]-(b)) 
where id(a) = 123 and id(c) = 456 
return nodes(p1)+nodes(p2) as nodes, relationships(p1)+relationships(p2) as rels;

Это, однако, дает мне слишком много узлов, которые даже не задействованы, и обработка этого запроса занимает вечность.Я думаю, это потому, что я не уверен, используется ли один и тот же узел (b) в 2 функциях allShortestPaths.Это будет результат более или менее:

       /-(v2)
      /-(v1)
(a)-(x1)-(b)-(x2)-(c)
 \-(y1)   \-(z1)-(z2)

Идеальным решением будет что-то вроде этого:

(a)-(x1)-(b1)-(x2)-(c)
 \-(b2)-(y1)-(y2)-(c)

Это означает, что между (a) и 2 найдены 2 кратчайших пути.(c), которые проходят через узел (b) с меткой 'SomeImportantLabel'.

1 Ответ

0 голосов
/ 25 октября 2018

Вы можете использовать функции ANY / ALL / SINGLE / NONE для фильтрации результатов пути в части WHERE, и Neo4j может применять эти фильтры (по крайней мере для ALL / NONE, если необходимо) при поиске пути.

Так, например ...

MATCH p = allShortestPaths((a)-[*]-(c))
WHERE ID(a) = 123 AND ID(c) = 456 
AND ANY(b in NODES(p) WHERE a<>b<>c AND b:SomeImportantLabel)  
RETURN nodes(p) as nodes, relationships(p) as rels;

Кроме того, хотя мы можем обрезать начало / конец списка из ЛЮБОГО набора фильтров, планировщик Cypher предпочитает, чтобы один и тот же фильтр применялся ко всему пути., так что лучше исключить их в части WHERE.

...