Overview
The ab().src().dest().depth()
statement retrieves paths between two sets of nodes, pairing each node in src()
with each node in dest()
for pathfinding. If n
nodes are specified by src()
and m
nodes by dest()
, a total of n * m
node pairs will be considered.
Syntax
ab().src(<filter?>).dest(<filter?>).depth(<range>)
- Statement alias: Type
PATH
- Methods:
Method |
Param |
Description | Optional |
Alias Type |
---|---|---|---|---|
src() |
<filter?> |
The filtering condition enclosed in {} , or an alias to specify the set of nodes as traversal sources. Leaving it blank will target all nodes. |
No | NODE |
dest() |
<filter?> |
The filtering condition enclosed in {} , or an alias to specify the set of nodes as traversal destinations. Leaving it blank will target all nodes. |
No | NODE |
depth() |
<range> |
The number of steps to travese (N≥1):
|
No | N/A |
shortest() |
<weight?> |
Leaves it blank to find unweighted shortest paths or specifies a numeric edge property in the format @<schema>.<property> to find weighted shortest paths. The property shouldn't have negative values, and edges without these properties are disregarded. Only supports depth(N) for the shortest paths within N steps. |
Yes | N/A |
node_filter() |
<filter?> |
The filtering condition enclosed in {} for all intermediate nodes in the paths. Leaving it blank applies no restriction. |
Yes | N/A |
edge_filter() |
<filter?> |
The filtering condition enclosed in {} for edges in the paths. Leaving it blank applies no restriction. |
Yes | N/A |
path_ascend() |
<property> |
Specifies a numeric edge property in the format @<schema>.<property> to find paths where this property values ascend from src() to dest() ; edges without these properties are disregarded. |
Yes | N/A |
path_descend() |
<property> |
Specifies a numeric edge property in the format @<schema>.<property> to find paths where this property values descend from src() to dest() ; edges without these properties are disregarded. |
Yes | N/A |
direction() |
<leftRight> |
Specifies the direction of all edges in the paths, which can be left or right . |
Yes | N/A |
no_circle() |
/ | Excludes paths that form circles. A path has circles when it has repeated nodes. An exception is when src() and dest() specify the same node and that node does not appear as an intermediate node, the corresponding paths will still be returned. |
Yes | N/A |
limit() |
<N> |
Limits the number of paths (N ≥-1) returned for each node pair; -1 includes all paths. |
Yes | N/A |
Example Graph
To create the graph, execute each of the following UQL queries sequentially in an empty graphset:
create().edge_property(@default, "weight", int32)
insert().into(@default).nodes([{_id:"A"}, {_id:"B"}, {_id:"C"}, {_id:"D"}, {_id:"E"}, {_id:"F"}])
insert().into(@default).edges([{_from:"A", _to:"C", weight:1}, {_from:"E", _to:"B", weight:1}, {_from:"A", _to:"E", weight:4}, {_from:"D", _to:"C", weight:2}, {_from:"E", _to:"D", weight:3}, {_from:"B", _to:"A", weight:2}, {_from:"F", _to:"A", weight:4}])
Finding Paths of Varying Depths
Within N Steps
To find paths within 3 steps between nodes A
, C
and nodes D
, E
:
ab().src({_id in ["A", "C"]}).dest({_id in ["D", "E"]}).depth(:3) as p
return p
A <- B <- E -> D
A -> C <- D
A -> E -> D
C <- A -> E -> D
C <- D
A <- B <- E
A -> C <- D <- E
A -> E
C <- A <- B <- E
C <- A -> E
C <- D <- E
Exact N Steps
To find paths with exact 3 steps between nodes A
, C
and nodes D
, E
:
ab().src({_id in ["A", "C"]}).dest({_id in ["D", "E"]}).depth(3) as p
return p
A <- B <- E -> D
C <- A -> E -> D
A -> C <- D <- E
C <- A <- B <- E
Within N to M Steps
To find paths with 2 to 3 steps between nodes A
, C
and nodes D
, E
:
ab().src({_id in ["A", "C"]}).dest({_id in ["D", "E"]}).depth(2:3) as p
return p
A <- B <- E -> D
A -> C <- D
A -> E -> D
C <- A -> E -> D
A <- B <- E
A -> C <- D <- E
C <- A <- B <- E
C <- A -> E
C <- D <- E
Finding Unweighted Shortest Paths
To find shortest paths within 5 steps between node A
and node D
:
ab().src({_id == "A"}).dest({_id == "D"}).depth(5).shortest() as p
return p
A -> C <- D
A -> E -> D
Finding Weighted Shortest Paths
To find shortest paths weighted by the property @default.weight
within 5 steps between node A
and node D
, and compute the total weights in paths:
ab().src({_id == "A"}).dest({_id == "D"}).depth(5).shortest(@default.weight) as p
call {
with p
uncollect pedges(p) as edges
return sum(edges.weight) as weights
}
return p, weights
Result:
p | weights |
---|---|
A -> C <- D |
3 |
Filtering Intermediate Nodes
To find paths within 5 steps between node F
and nodes E
without passing through node D
:
ab().src({_id == "F"}).dest({_id == "E"}).depth(:5).node_filter({_id != "D"}) as p
return p
F -> A <- B <- E
F -> A -> E
Filtering Edges
To find paths within 3 steps between node A
and node E
, where the property weight
of each edge is greater than 1:
ab().src({_id == "A"}).dest({_id == "E"}).depth(:3).edge_filter({weight > 1}) as p
return p
A -> E
Setting Ascending or Descending Edge Property Values
To find paths within 3 steps between node A
to node E
, where the property @default.weight
values ascend along the path:
ab().src({_id == "A"}).dest({_id == "E"}).depth(:3).path_ascend(@default.weight) as p
return p
A -> C <- D <- E
A -> E
To find paths within 3 steps between node A
to node E
, where the property @default.weight
values descend along the path:
ab().src({_id == "A"}).dest({_id == "E"}).depth(:3).path_descend(@default.weight) as p
return p
A <- B <- E
A -> E
Setting Edge Directions
To find paths within 2 to 4 steps between nodes A
, C
and node E
with all edges pointing to the left:
ab().src({_id in ["A", "C"]}).dest({_id == "E"}).depth(2:3).direction(left) as p
return p
A <- B <- E
C <- A <-B <- E
C <- D <- E
Excluding Circles
To find paths with exact 4 steps between node A
and E
without any circles:
ab().src({_id == "A"}).dest({_id == "C"}).depth(4).no_circle() as p
return p
A <- B <- E -> D -> C
Without the no_circle()
method, three paths will be returned:
ab().src({_id == "A"}).dest({_id == "C"}).depth(4) as p
return p
A <- B <- E <- A -> C
A <- B <- E -> D -> C
A -> E -> B -> A -> C
Using limit()
To find paths within 3 steps between nodes A
, C
and node E
, return only one path for each node pair:
ab().src({_id in ["A", "C"]}).dest({_id == "E"}).depth(:3).limit(1) as p
return p{*}
A <- B <- E
C <- A <- B <- E
Using OPTIONAL
In this query, the ab()
statement executes two times, each time using one record from n
. With the OPTIONAL
prefix, the query returns null
if no result is found during execution:
find().nodes({_id in ["A","C"]}) as n
optional ab().src(n).dest({_id == "D"}).depth(1) as p
return p
null
C <- D
Without the prefix OPTIONAL
, only one record is returned:
find().nodes({_id in ["A","C"]}) as n
ab().src(n).dest({_id == "D"}).depth(1) as p
return p
C <- D