UltipaDocs
Try Playground
  • Introduction
  • Terminologies
    • Graphset
    • Schema
    • Property
    • Constraints
    • Insert
    • Overwrite or Insert
    • Upsert
    • Update
    • Delete
    • Find Nodes
    • Find Edges
      • AB
      • Autonet
      • Spread
      • Path Template
      • K-Hop
      • K-Hop Template
    • GROUP BY
    • ORDER BY
    • SKIP
    • LIMIT
    • WHERE
    • RETURN
    • WITH
    • UNCOLLECT
    • UNION
    • UNION ALL
    • CALL
    • All Functions
    • Path Functions
    • Aggregate Functions
    • Mathematical Functions
    • Trigonometric Functions
    • String Functions
    • List Functions
    • Datetime Functions
    • Spatial Functions
    • Table Functions
    • Null Functions
    • Type Conversion Functions
  • Operators
  • Expressions
    • Index
    • Full-text Index
    • Vector Index
    • Cache
    • Overview
    • Managing HDC Graphs
    • HDC Graph Queries
    • Process
    • Job
    • Execution Plan
    • Alias
    • Filter
    • Values and Types
    • Data Flow in Queries
    • Comments
    • Reserved Words
  • Access Control
  1. Docs
  2. /
  3. UQL
  4. /
  5. Find Paths

AB

Overview

The ab().src().dest().depth() statement retrieves paths between two sets of nodes by 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

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. If left blank, all nodes are targeted.NoNODE
dest()<filter?>The filtering condition enclosed in {}, or an alias to specify the set of nodes as traversal destinations. If left blank, all nodes are targeted.NoNODE
depth()<range>The number of steps to travese (N≥1):
  • depth(N): N edges
  • depth(:N): 1 ~ N edges
  • depth(N:M): N ~ M edges
NoN/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.YesN/A
node_filter()<filter?>The filtering condition enclosed in {} for all intermediate nodes in the paths. If left blank, no restriction is applied.YesN/A
edge_filter()<filter?>The filtering condition enclosed in {} for edges in the paths. If left blank, no restriction is applied.YesN/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.YesN/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.YesN/A
direction()<leftRight>Specifies the direction of all edges in the paths, which can be left or right.YesN/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.YesN/A
limit()<N>Limits the number of paths (N≥-1) returned for each node pair; -1 includes all paths.YesN/A

Example Graph

To create the graph, execute each of the following UQL queries sequentially in an empty graphset:

UQL
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 or C and nodes D or E:

UQL
ab().src({_id in ["A", "C"]}).dest({_id in ["D", "E"]}).depth(:3) as p
return p

Result: p

Exact N Steps

To find paths with exact 3 steps between nodes A, C and nodes D, E:

UQL
ab().src({_id in ["A", "C"]}).dest({_id in ["D", "E"]}).depth(3) as p
return p

Result: p

Within N to M Steps

To find paths with 2 to 3 steps between nodes A, C and nodes D, E:

UQL
ab().src({_id in ["A", "C"]}).dest({_id in ["D", "E"]}).depth(2:3) as p
return p

Result: p

Finding Unweighted Shortest Paths

To find the shortest paths within 5 steps between node A and node D:

UQL
ab().src({_id == "A"}).dest({_id == "D"}).depth(5).shortest() as p
return p

Result: p

Finding Weighted Shortest Paths

To find the shortest paths weighted by the property @default.weight within 5 steps between node A and node D, and compute the total weight of the paths:

UQL
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
3

Filtering Intermediate Nodes

To find paths within 5 steps between node F and nodes E without passing through node D:

UQL
ab().src({_id == "F"}).dest({_id == "E"}).depth(:5).node_filter({_id != "D"}) as p
return p

Result: p

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:

UQL
ab().src({_id == "A"}).dest({_id == "E"}).depth(:3).edge_filter({weight > 1}) as p
return p

Result: p

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:

UQL
ab().src({_id == "A"}).dest({_id == "E"}).depth(:3).path_ascend(@default.weight) as p
return p

Result: p

To find paths within 3 steps between node A to node E, where the property @default.weight values descend along the path:

UQL
ab().src({_id == "A"}).dest({_id == "E"}).depth(:3).path_descend(@default.weight) as p
return p

Result: p

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:

UQL
ab().src({_id in ["A", "C"]}).dest({_id == "E"}).depth(2:3).direction(left) as p
return p

Result: p

Excluding Circles

To find paths with exact 4 steps between node A and E without any circles:

UQL
ab().src({_id == "A"}).dest({_id == "C"}).depth(4).no_circle() as p
return p

Result: p

Without the no_circle() method, three paths will be returned:

UQL
ab().src({_id == "A"}).dest({_id == "C"}).depth(4) as p
return p

Result: p

Using limit()

To find paths within 3 steps between nodes A, C and node E, return only one path for each node pair:

UQL
ab().src({_id in ["A", "C"]}).dest({_id == "E"}).depth(:3).limit(1) as p
return p{*}

Result: p

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:

UQL
find().nodes({_id in ["A","C"]}) as n
optional ab().src(n).dest({_id == "D"}).depth(1) as p
return p

Result: p

Without the prefix OPTIONAL, only one record is returned:

UQL
find().nodes({_id in ["A","C"]}) as n
ab().src(n).dest({_id == "D"}).depth(1) as p
return p

Result: p