【问题标题】:How to eliminate all paths that pass through particular document or vertex while during Graph Traversal in ArangoDB如何在 ArangoDB 中的图形遍历期间消除通过特定文档或顶点的所有路径
【发布时间】:2019-08-30 07:44:02
【问题描述】:

我正在尝试在这里进行图形遍历

我在 ArangoDB 中创建了两个集合,一个文档集合 "Node" 和一个边缘集合 "Path"。我所有的节点都有一个name 属性(标签),并由边(线)连接,如上图所示。

我尝试以下查询来查找以 enderror 节点结尾的路径:

FOR v, e, p IN 1..10 OUTBOUND 'Node/start_0' Path     
OPTIONS { bfs: true}     
FILTER (v.name == "end" OR v.name == "error")     
RETURN CONCAT_SEPARATOR(' - ', p.vertices[*].name)

上述查询按预期工作并返回两条路径:

["start - decide - execute1 - error"
 "start - decide - execute2 - end"]

但我正在探索如何消除通过特定节点的所有相应路径。例如,我想消除所有通过 execute1 的路径。我试过这个查询:

 FOR v, e, p IN 1..10 OUTBOUND 'Node/start_0' Path     
 OPTIONS { bfs: true}     
 FILTER ((v.name == "end" OR v.name == "error") AND v.name != "execute1")     
 RETURN CONCAT_SEPARATOR(' - ', p.vertices[*].name)

但它不起作用 - 它仍然返回两条路径。

任何人都可以帮助我如何重新构建此查询以使其仅返回一个路径,即“开始 - 决定 - 执行 2 - 结束”?

【问题讨论】:

    标签: arangodb graph-traversal


    【解决方案1】:

    您的遍历具有 1..10 的可变深度,它将找到以下路径:

    1. 开始 - 决定
    2. 开始-决定-执行1
    3. 开始-决定-执行2
    4. 开始 - 决定 - 执行 1 - 错误
    5. 开始-决定-执行2-结束

    请注意如何返回具有一跳 (1) 和两跳 (2, 3) 的路径。它们在一到十跳之内。您的期望可能是遍历只会发出叶节点 (4, 5)。但是,它为您提供了所有五条路径。

    您的name 属性过滤条件针对v 进行测试,v 表示这些路径中的每一个的最后一个顶点

    • "decide" 不等于"end""error",所以过滤掉了路径1。
    • "execute1""execute2" 不等于 "end""error",所以路径 2 和 3 也被过滤掉了。
    • "error""end" 等于这些值中的任何一个,但它们也满足条件 != "execute1" - 您正在测试停止节点而不是此处路径上的所有节点,因此行为是正确的但不是什么你想要的

    您的选择是:

    • 过滤掉所有包含名称为"execute1":
      FILTER p.vertices[*].name NONE == "execute1" AND v.name IN ["end", "error"]的顶点的路径
    • 不要让遍历器通过"execute1" 使用PRUNE(自v3.4.5 和v3.5.0 起可用):
      PRUNE v.name == "execute1" … FILTER v.name IN ["end", "error"]
    • 不要让遍历器经过"execute1""end""error"(上述查询的优化):
      PRUNE v.name IN ["execute1", "end", "error"] … FILTER v.name IN ["end", "error"]

    请注意,PRUNE 将包括条件为真的顶点,即发现路径 2,但随后被FILTER 条件过滤掉。 PRUNE 单独不会过滤掉路径 2。但是,它将阻止从"execute1" 继续遍历,这意味着不会发现路径4。 FILTER 从结果中删除路径 1、2 和 3,只留下路径 5。

    还要注意PRUNE子句必须放在OPTIONS之前!

    FOR v, e, p IN 1..10 OUTBOUND 'Node/start_0' Path
    PRUNE v.name IN ["execute1", "end", "error"]
    OPTIONS { bfs: true }
    FILTER v.name IN ["end", "error"]
    RETURN CONCAT_SEPARATOR(' - ', p.vertices[*].name)
    

    结果:[ "start - decide - execute2 - end" ]

    文档:Pruning in Graph Traversals

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多