【问题标题】:Can this Neo4j query be optimized?这个 Neo4j 查询可以优化吗?
【发布时间】:2017-09-11 09:12:34
【问题描述】:

我有相当大的数据集(2000 万个节点,2 亿条边),最简单的 shortestPath 查询在几毫秒内完成,一切都很好。

但是...我需要允许 shortestPath 具有 999 类型的零或一关系,并且它只能是从起始节点开始的第一个。

所以,我的查询变成了这样:

MATCH (one:Obj{oid:'startID'})-[r1*0..1]-(b:Obj) 
WHERE all(rel in r1 where rel.val = 999) 
WITH one, b 
MATCH (two:Obj{oid:'endID'}), path=shortestPath((one) -[0..21]-(two)) 
WHERE ALL (x IN RELATIONSHIPS(path) 
WHERE (x.val > -1 and x.val<101) or (x.val=999 or x.val=998)) return path

当路径很短(最多 2-4)时,它会以毫秒为单位运行,但对于像 5++ 这样的路径,它可能需要 5 或 20 秒。也许我编写了低效的查询?

此问题将在可用时获得奖励。

【问题讨论】:

  • 当删除最后一个条件“WHERE ALL (x IN RELATIONSHIPS(path) WHERE (x.val > -1 and x.val
  • 我们不知道您有哪些索引,而且您的查询看起来像是从您的域中重新制定的,这使得回答变得更加困难。您能否在实际查询中发布EXPLAIN 的结果,以便我们看到正在执行的计划?
  • 另外,为什么b在这个查询中,它不在第二个匹配或RETURN中,看起来像浪费工作。此外,如果您有关系类型,则应该在这些路径上使用它们......它们不会根据 relType 进行区分,并且您正在寻找通过任何无向关系的非常长的路径。如果您指定 rel 的顺序和合适的类型(或类型集),它可能已经好很多了,但这取决于我们看不到的数据方面。
  • 感谢您的帮助!起初我搜索了 b 和 2 之间的最短路径,但它显示了路径 one-b 的所有附录(在可视模式下)。更改为 1 和 2 之间的最短路径显示相同的路线,没有不必要的附录。但是很慢......正如建议的那样,关系[0] 是对第一个关系施加条件的正确方法。

标签: performance neo4j cypher


【解决方案1】:

您的一些要求对我来说有点不清楚,所以我将重申我的理解并提供解决方案。

您想要检查起点和终点节点之间的最短路径。

返回的路径应该有零或一关系,val 为 999。如果它与该值是一关系,它应该是第一个。

这是基于该逻辑的尝试:

 MATCH (start:Obj {oid:'startID'}),
       (end:Obj {oid:'endID'}),
       path=shortestPath((start)-[1..21]->(end))
  WITH path, relationships(path) AS rels
 WHERE all(r IN relationships WHERE r.val != 999)
    OR (relationships[0].val = 999
        AND all(r IN relationships[1..] WHERE r.val != 999))
RETURN path

我还没有机会测试实际数据,但希望这种逻辑和方法至少可以为您指明正确的方向。

另请注意:最后的整个 WHERE 子句可能会简化为:

 WHERE all(r IN relationships[1..] WHERE r.val != 999)

意味着您甚至不需要检查第一个关系。

【讨论】:

  • 非常感谢,乔纳森!操作员关系 [0] 是我错过的!明天开始赏金,你是赢家。较长的选项有几个语法错误,但较短的选项效果很好。只是... 而不是 != 和关系(路径)[1..] 而不是关系[1..]
  • 很酷,很高兴它有帮助。我想我的意思是说 rels[1..]。很好地抓住不等于,在我的临时查询中经常抓住我......旧习惯很难改掉。 :)
  • 你也可以WHERE ALL(r in TAIL(RELATIONSHIPS(path)) WHERE r.val != 999)。这样你就不需要 with,查询可以提前终止。 (functions 的其余部分)
  • 哦,伙计!你的问题今天让我很难受。它只是默默地忽略了一些长度为 2 的路径。没有找到 a-b-c 之间的最短路径,a-b 之间是,b-c 之间也是。将尝试向 Neo 报告错误... :(((
猜你喜欢
  • 2019-02-24
  • 1970-01-01
  • 2011-04-25
  • 1970-01-01
  • 1970-01-01
  • 2023-03-28
  • 2018-01-11
  • 1970-01-01
  • 2022-10-30
相关资源
最近更新 更多