我有一个图表,在Neo中有5亿个节点和边缘。我想找到2个节点之间的最短路径,避免超级节点(即使它比它们上面有超级节点的路径长)。
以下查询适用于较小的图形,但从不完成我正在处理的大小的图形:
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 :(得分:2)
您还可以尝试为超节点添加标签:
event
这会在您的数据上运行并完成吗?你有多少个超节点和普通节点?
然后尝试:
MATCH (x:Node)
WHERE size((x)--())>1000
SET n:Supernode
我认为标签检查更快。
答案 1 :(得分: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/