【问题标题】:AQL to validate path to node用于验证节点路径的 AQL
【发布时间】:2018-09-07 18:24:59
【问题描述】:

我们需要有一些 AQL 来验证实体的特定路径。由于需要扫描整个集合,当前的解决方案性能很差。

例如这里我们有 3 个实体“类型”:a、b、c(尽管它们都在一个集合中)和它们之间的特定边集合,我们想确定 _key "123" 和 _key " 之间是否存在连接234" 完全通过 a -> b -> c。

FOR a IN entities FILTER e._key == "123" FOR b IN 1..1 OUTBOUND e edges_a_to_b FOR c IN 1..1 INBOUND e_1 edges_c_to_b FILTER e_2._key == "234" ...

这会很快散开!

我们有另一个解决方案,我们使用 SHORTEST PATH 并指定适当的 DIRECTION 和边缘集合,这要快得多(>100 倍)。但担心这种方法不能完全满足我们的一般情况......边的顺序没有强制执行,我们可能不得不多次通过同一个边集合,而我们不能用这种语法来做到这一点。

还有其他方法,可能涉及遍历中的路径?

谢谢! 丹。

【问题讨论】:

  • the order of the edges is not enforced 是什么意思?可以从 B 类节点到 C 类节点的边缘点,但也可以反过来,从 C 到 B?或者可能存在多个(最短)路径并且您需要检查特定路径?如果是这样,测试特定路径的原因是什么?路径上的边缘是否有过滤条件?
  • 该应用程序用于一般安全检查。想象一下全科医生,其中类型是手术、医生、患者。医生可以管理他自己的患者(医生 -> 患者),但只能读取他的其他医生的患者(医生 -> 手术 -> 医生 -> 患者)。需要知道个别医生和患者是否被第一个病例或第二个病例联系起来。对于我们的实际情况,这个安全检查可能会多次命中同一个关系对,并且可能存在更短的路径,不满足表达的关系条件。
  • 不需要对边缘进行过滤。

标签: arangodb


【解决方案1】:

如果我理解正确,您总是知道两个顶点之间所需的确切路径。

a -> b -> c 为例,有效结果将具有: path.vertices == [a, b, c] 因此,我们可以使用此路径对其进行过滤,这仅在您使用单个遍历步骤而不是多个遍历步骤时才有效。 所以我们尝试du的是以下模式:

FOR c,e, path IN <pathlength> <direction> <start> <edge-collections>
  FILTER path.vertices[0] == a // This needs to be formulated correctly
  FILTER path.vertices[1] == b // This needs to be formulated correctly
  FILTER path.vertices[2] == c // This needs to be formulated correctly
  LIMIT 1 // We only net exactly one path, so limit 1 is enough
  [...]

所以有了这个提示,就可以用以下方式编写查询:

FOR a IN entities
  FILTER a._key == "123"
  FOR c, e, path IN 2 OUTBOUND a edges_a_to_b, INBOUND edges_b_to_c
    FILTER path.vertices[1] == /* whatever identifies b e.g. vertices[1].type == "b" */
    FILTER path.vertices[2]._key == "234"
    LIMIT 1 /* This will stop as soon as the first match is found, so very important! */
    /* [...] */

这将允许优化器尽早应用过滤条件,并且将(几乎)使用与最短路径实现相同的算法。 诀窍是使用一次遍历而不是多次遍历来节省内部开销并实现更好的优化。

还要考虑到反方向搜索可能会更好:

例如而不是a -&gt; b -&gt; c 检查c &lt;- b &lt;- a,这可能会更快。 这取决于每个节点的边数。 我假设一个医生有很多手术,但一个病人很可能只有少量手术,所以最好从病人开始向后检查,而不是从医生开始向前检查。

请告诉我这已经有所帮助,否则我们可以讨论更多细节,看看我们是否可以找到一些进一步的优化。

免责声明:我是 ArangoDB 核心开发团队的一员

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-10
    相关资源
    最近更新 更多