【问题标题】:Optimizing Neo4j Query for Path search为路径搜索优化 Neo4j 查询
【发布时间】:2020-03-26 15:19:48
【问题描述】:
  • Neo4j 版本:3.5.16

  • 你使用什么样的 API/驱动程序:Python API with py2neo to run the query with graph.run()

  • Py2neo 版本:4.3.0。

大家好,

我正在尝试优化密码查询以检索可变长度路径。

每次数据到达时都会创建图表,并且 startNode 和 endNode 固定在它们的 name 属性上。创建图表后,我有一个 startNode 和一个 endNode,推论/目标是:

“从最小长度为 X 和最大长度为 Y 的所有可能路径中,我想找到产生最高聚合关系值的最短路径”。

我实际上设法做的是:使用以下 cyper 查询“获取 X 和 Y 之间产生最高聚合关系值的长度路径”:

MATCH path = (startN:Batch { name: $startNode })-[:CHANGES_TO*4..7]->(endN:Batch { name: $endNode })
RETURN path,
REDUCE (s = 1, r IN RELATIONSHIPS(path) | s * r.rateValue) AS finalBatchValue
ORDER BY finalBatchValue DESC 
LIMIT 1

但是,运行需要一些时间。 ¿ 有人可以提供有关如何优化这一点的想法,既要完成最短路径的目标,又要优化查询以尽可能快地运行?

我试图让它与 allShortestPaths 或 Dijkstra 等 APOC 方法一起工作,但没有成功;它最终返回了最短路径,我无法确定要考虑的最小节点数量。

非常感谢任何帮助。

【问题讨论】:

  • 嘿,我对你的预期结果有点怀疑。假设 p1 的长度为 4 ,关系值为 100 。 p2 的长度为 6 ,关系值为 120 。哪个是您的预期输出,p1 还是 p2?
  • 嘿,对不起,也许我没有说明哪个是流行的指标;它应该是p1。我想将最短路径作为第一个目标,所以要完全清楚,在另一个例子中,在 p1 长度为 4 和关系值 120 和 p2 长度为 4 和关系值 140 的情况下,我选择 p2。这有意义吗?谢谢!

标签: neo4j cypher py2neo neo4j-apoc


【解决方案1】:

因为您基本上是在寻找最短长度的最强的。您可以通过一个技巧来解决性能问题。 您可以查询固定长度而不是可变长度的图形。但是您必须查询 n2-n1+1 次,在您的情况下为 4 次,首先是长度为 4,然后是 5,依此类推。 如果您在任何时候找到路径,您可以停止查询。 这种方法将大大减少每次加载的数据。但是您必须多次点击图表。四次点击方法所花费的平均时间很可能少于可变长度的单次点击。 原因是如果你找到一个较短长度的解决方案,你就不会计算所有长度较长的路径。 因为,路径越长,所花费的时间就会成倍增长。

仅使用 cypher 是不可能的。一种方法是在 java 中编写 neo4j 过程并在 cypher query 中使用它。 第二种方法是:使用不同的查询点击 neo4j。 我在这里为您的案例编写 python 代码,

query = 'MATCH path = (startN:Batch { name: $startNode })-[:CHANGES_TO*LENGTH_PARAM]->(endN:Batch { name: $endNode })
RETURN path,
REDUCE (s = 1, r IN RELATIONSHIPS(path) | s * r.rateValue) AS finalBatchValue
ORDER BY finalBatchValue DESC 
LIMIT 1'
for length in range(4,8):
      query  = query.replace('LENGTH_PARAM',str(x))
      result = graph.run(query)
      #if result size > 0 
      #your implementation 
      #final_result= result['path'] 
      #return final_result

这就是它的工作原理,在最坏的情况下,您需要为每个开始、结束节点对点击图表四次。网络调用增加,但平均花费的时间应该减少。

使用 java 插件,它可以像以前的查询一样减少到一次点击,因为您可以在 java 代码中执行循环部分。

【讨论】:

  • 嗯,我明白你的意思,但我不明白如何将其转换为具有这些条件的密码查询。你能提供一些例子吗?如果我有,我可以直接在这里测试。
  • 当然。更新答案
  • 非常感谢!我刚刚运行它并了解其含义。当我们从最小值开始循环时,如果路径的结果是返回的那个长度,由于我们没有达到最大长度,导致图形处理的时间要少得多。我也试图达到最大值,在我的实现中,这里的 10 秒是 11 秒,所以几乎相同。很好的答案和很好的解决方法!
  • 很高兴它有帮助:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-02-23
  • 1970-01-01
  • 1970-01-01
  • 2013-03-16
  • 2016-01-06
相关资源
最近更新 更多