AQL - graph traversal - filtering on path with complex condition

740 views Asked by At

I would like to ask how to best traverse graph and return only subgraph based on complex condition which must be satisfied by all nodes from root to leaves. In other words, I need some mechanism such that when the condition on any intermediate level is not met, traversal is stopped (none nested node is processed and returned to output)

Let's say I have the following graph:

A -> B -> C (active=false) -> D

where I deactivated node C (note the flag active=false means that all subgraph is deactivated including C and D).

According to documentation I can easily construct such filter via filtering on path, wildcard [*] and ALL keyword, which also stops traversing when condition on C is not met. With simple condition this works great:

for v,e,p in 1..100 outbound 'test/A' graph 'testGraph'
  filter p.vertices[*].active ALL != false return v
  // returns A, B

Now I have another graph where each node is either fixed or has some validity timespan (from, to) attributes:

A (type="fixed") -> B (from=2,to=3) -> C (from=1, to=5) -> D (type="fixed")

Now I would like to return only subgraph where all (intermediate) nodes are either fixed or satisfy time condition from>=2 and to<=3. I need that A,B are returned.

for v,e,p in 0..100 outbound 'test/A' graph 'testGraph'
  filter p.vertices[*].type ALL == 'fixed' or
    (p.vertices[*].from ALL >= 2 and p.vertices[*].from ALL <= 3)
  return v

However this is obviously wrong (and returns only A), logically I need to add ALL keyword at the beginning of the condition (I need that the condition is applied on each level and when the condition is not met, traversing is stopped), however this is not supported:

filter ALL(p.vertices[*].type == 'fixed' or
  (p.vertices[*].from >= 2 and p.vertices[*].from <= 3)

Classical approach via filtering on vertices does not meet my needs, because it doesn't stop traversing when the condition is not met, i.e. the following returns A,B,D (C is skipped but I also need to prune subtree of C such that D is not on output):

for v,e,p in 0..100 outbound 'test/A' graph 'testGraph'
  filter  v.type == 'fixed' or 
    (v.from >= 2 and v.from <= 3)
  return v

Any ideas? Thank you.

1

There are 1 answers

0
Maximilian Kernbach On

The AQL PRUNE feature was introduced in ArangoDB versions 3.4.5 and 3.5.0. Using the AQL keyword PRUNE the traversing is stopped when a condition on the vertex, the edge, the path or any variable defined before before is met.

Pruning is the easiest variant to formulate conditions to reduce the amount of data to be checked during a search. So it allows to improve query performance and reduces the amount of overhead generated by the query. Pruning can be executed on the vertex, the edge and the path and any variable defined before.

This video tutorial shows the difference between FILTER and the new PRUNE with a hands-on example. You can find more details in the documentation.