【问题标题】:How to stop traversal based on inbound edge如何根据入站边缘停止遍历
【发布时间】:2017-07-31 12:37:05
【问题描述】:

我在 ArangoDB 中有一个图,其中包含两个顶点集合 P 和 F,以及一个包含两种类型边的边集合:fp 和 hp。

请注意,上面的图像已经过简化 - “F”节点通过更多“fp”边连接到其他 F 节点。换句话说,我事先不知道(例如)“F4”是否有入站“fp”边缘或更多。

我想使用一个 AQL 查询来遍历图形,从节点 PA 开始,但在没有入站“hp”边的任何顶点处停止。 Documentation 表示停止遍历的方法是使用如下查询:

FOR v, e, p IN 0..100 OUTBOUND 'P/PA'GRAPH 'test'
  FILTER p.<vertices|edges>... <condition>
  RETURN v

我想看看:

PA, PC, PE, PF 

但如果不首先在“P”节点上填充一个新属性,表明它们具有入站“fp”边缘,我不知道如何实现这一点。如果我这样做了,那么这将是可能的:

FOR v, e, p IN 0..100 OUTBOUND 'P/PA'GRAPH 'test'
  FILTER p.vertices[*].hasFP ALL == true
  RETURN v

有没有一种方法可以在一个 AQL 查询中实现这一目标而无需预处理步骤?

【问题讨论】:

    标签: graph-databases arangodb graph-traversal


    【解决方案1】:

    您可以使用以下查询来执行此操作。它在您的起点P/PA 开始遍历,并检查是否没有连接边(起点本身需要)或边的typehp。然后它开始对与P/PA 直接或间接连接的每个找到的顶点进行另一次遍历,深度为1,方向INBOUND。在这里它过滤边缘type等于fp并从周围遍历返回顶点。这个RETURN需要DISTINCT,否则你的起点会被返回两次。

    FOR v, e, p IN 0..100 OUTBOUND 'P/PA' GRAPH 'test'
      FILTER e == null
      OR e.type == 'hp'
      FOR v1, e1, p1 IN 1 INBOUND v._id GRAPH 'test'
        FILTER e1.type == 'fp'
        RETURN DISTINCT v
    

    【讨论】:

    • 嗯不幸的是,这仍然在结果中返回“PD”,并且顶点以非深度优先序列返回......
    • 好吧抱歉,现在我了解您的情况了。目前 AQL 无法做到这一点。您对hasFP 标志的想法应该是目前最好的解决方案。
    【解决方案2】:

    如果我对问题的理解正确,答案是:使用子查询来检查条件。然而不幸的是,目前 AQL 不支持剪枝,因此(对于当前版本,即 3.2),这种方法可能太慢了。

    简而言之,子查询如下所示:

    (FOR v0 IN p.vertices
       LET hasP = (FOR v1, e1 IN 1..1 INBOUND v0 GRAPH “test”
                     FILTER e1.type == “fp”
                     COLLECT WITH COUNT INTO c
                     RETURN c>0)
       FILTER hasP
       COLLECT WITH COUNT INTO c
       RETURN c == LENGTH(p.vertices) )
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-03-22
      • 1970-01-01
      • 2015-11-23
      相关资源
      最近更新 更多