如何根据入站边缘停止遍历

问题描述 投票:1回答:2

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

enter image description here

请注意,上面的图像已经简化 - “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
2个回答
1
投票

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

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

0
投票

如果我正确理解了问题,答案是:使用子查询来检查条件。不幸的是,目前,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) )
© www.soinside.com 2019 - 2024. All rights reserved.