2017-03-27 132 views
5

我有一个在Neo中有5亿个节点和边的图。我想找到避免超节点的2个节点之间的最短路径(即使它们比具有超节点的路径长)。Neo4j中没有超节点的最短路径

下面的查询工作正常较小的图形,但从来没有完成对我处理大小的图表:

MATCH (n:Node { id:'123'}),(m:Node { id:'234' }), p = shortestPath((n)-[*..6]-(m)) 
WHERE NONE(x IN NODES(p) WHERE size((x)--())>1000) 
RETURN p 

如果我删除WHERE子句是超级快。通常是亚秒。

我该如何加快速度?预先计算节点度并索引它们会有帮助吗?我是否应该复制所有与超节点相邻的边,并给它们一个新的标签,并将它们用于我的shortestPath查询而不使用WHERE子句?还有其他建议吗?

+0

会发生什么事,如果你删除标签? (x) - ())> 1000) –

+0

好点。道歉,我实际上在WHERE子句中没有标签测试它。第一个标签有错误。第二个标签似乎没有任何区别。让我更新我的问题以删除标签。作为参考它最初看起来像这样: WHERE NONE(x:Node IN NODES(p)WHERE size((x:Node) - ())> 1000) – Tom

回答

2

据我所知,当WHERE ALL仅包含关系(而不是节点)时,Neo4j最短路径实现修剪路径。如果它不能修剪查询,它会找到所有的路径然后过滤它们(慢)。

正如马丁说,你可以添加一个标签:

MATCH (x:Node) 
WHERE size((x)--())>1000 
SET n:Supernode 

,然后通过边询问节点的标签:

MATCH p = shortestPath((n:Node { id:'1'})-[*..6]-(m:Node { id:'2' })) 
WHERE ALL(rel IN relationships(p) WHERE not (startNode(rel):Supernode or endNode(rel):Supernode)) 
RETURN p 

这将使Neo4j的使用进行了优化,双向,宽度优先(快速)查询。

一些更多的阅读这里: https://neo4j.com/docs/developer-manual/current/cypher/execution-plans/shortestpath-planning/

2

你也可以尝试添加一个标签为超:

MATCH (x:Node) 
WHERE size((x)--())>1000 
SET n:Supernode 

请问您的数据这一运行并完成?你有多少个超节点和正常节点?

然后尝试:

MATCH (n:Node { id:'123'}),(m:Node { id:'234' }) 
WITH n, m 
MATCH p = shortestPath((n)-[*..6]-(m)) 
WHERE NONE(x IN NODES(p) WHERE (x:Supernode)) 
RETURN p 

我想一个标签检查速度更快。

+0

谢谢。这并不能解决问题,但它很有用。所以我有几乎0.5G的节点。我能够在9米内运行第一个查询来标记超节点。其中有525个(即程度> 1k)。 不幸的是,如果在节点n和m之间有一个超节点,那么第二个查询仍然是永久的。据我所知,如果在这些节点附近没有超级节点,速度非常快。 – Tom

相关问题