AllPaths
Selects every matching path. Built by PathPattern.all.
Methods
.paths()
AllPaths.paths() -> DerivedColumnReturn one PathTraversal per matching path.
Enumeration uses walk semantics: nodes and edges may repeat, so cycles in the graph can result in arbitrarily many paths.
Returns:
DerivedColumn-PathTraversalvalues, one per matching path. Use it insideModel.where/Model.select, and read the per-path details (length,nodes,relationships,relationship_fields) via the correspondingPathTraversalproperties.
Examples:
p = m.path(Person.follows.repeat(1, 3)).where(Person.name == "Alice").all().paths()m.where(p).select( p, p.length, p.nodes["index"], Person(p.nodes).name.alias("node")).inspect()# p length index node# 0 6w6baylbPzQBFBq7X+77Ug 1 0 Alice# 1 6w6baylbPzQBFBq7X+77Ug 1 1 Bob# 2 IBUHvCZTYTKnBRjIey8suw 2 0 Alice# 3 IBUHvCZTYTKnBRjIey8suw 2 1 Bob# 4 IBUHvCZTYTKnBRjIey8suw 2 2 DavidEach distinct p value identifies one path; rows sharing a p describe the
nodes visited along it.
Notes:
Only the path’s endpoint identifiers unify with the enclosing scope. Filters on
interior nodes must be attached with PathPattern.where on the pattern;
a filter referencing interior nodes placed in an enclosing
Model.where cannot be routed into the path and
raises.
Performance: Enumerating all paths is worst-case exponential in the size of the
graph and thus may be EXTREMELY EXPENSIVE! Try to make your path pattern as
selective as possible, and run on smaller test data when building your model and
query for path count first. Confirm that your graph is acyclic via Graph.is_acyclic.
Unless you need variable repeats or enumeration of nodes and edges along the path,
consider using regular PyRel to express your query instead of .all().paths().
If you only need to know whether or which endpoints are connected — not
the paths themselves — use PathPattern.exists, which runs in polynomial time.
.count()
AllPaths.count() -> AggregateReturn the number of matching paths.
The returned object acts like any other PyRel sum or count aggregate. When
used bare, it has an implied empty .per(), so returns the single global count
of matching paths, exactly like a bare count(x) aggregates globally. Group the
count by applying .per(...) to the result with the pattern’s endpoint
identifiers: .per(initial_node, final_node) counts per connected pair,
.per(final_node) counts per final node, and so on.
Returns:
Aggregate- The Integer count, usable insideModel.where/Model.select, grouped by an optional.per(...)at the use site.
Raises:
relationalai.util.error.RAIException-PathNonDeterminismErrorif the pattern is ambiguous. Counting requires the pattern to be deterministic, i.e., there is only one way to match each path. An ambiguous pattern likepath(x.follows.repeat(0, 1), y.follows.repeat(0, 1), z), wherexandyare Refs of the same Concept, raises when used with this method.
Examples:
Define the count of paths from each criminal to each suspect. Suppose the
below pattern path(Criminal.works_with.repeat(1, 5), suspect) matches:
- 3 paths of length 1 from Alice to Bob
- 2 paths of length 2 from Alice to Bob
- 1 path of length 3 from Alice to Charlie
Unlike
AllShortestPaths.count, every path is counted, not only the shortest ones.
suspect = Person.ref()path_counts = m.path(Criminal.works_with.repeat(1, 5), suspect).all().count()Select the number of paths, grouped by both path endpoints, assuming that Alice is the only Criminal in the model:
m.select(Criminal.name, suspect.name, path_counts.per(Criminal, suspect)).inspect()# name name_2 sum# 0 Alice Alice <NA># 1 Alice Bob 5# 2 Alice Charlie 1Select the total number of paths:
m.select(path_counts).inspect()# sum# 0 6Select the number of paths, grouped by the final node:
m.select(suspect.name, path_counts.per(suspect) | 0).inspect()# name v0# 0 Alice 0# 1 Bob 5# 2 Charlie 1Select the suspects with 2 or more paths from a Criminal:
m.where(path_counts.per(suspect) >= 2).select(suspect.name).inspect()# name# 0 BobUnlike .all_shortest().per().count(), the pattern need not name its endpoints:
m.select(m.path(Criminal.works_with.repeat(1, 3)).all().count())Notes:
Only the path’s endpoint identifiers unify with the enclosing scope. Filters on
interior nodes must be attached with PathPattern.where on the pattern;
a filter referencing interior nodes placed in an enclosing
Model.where cannot be routed into the path and
raises.
Counting uses the same walk semantics as AllPaths.paths: nodes and edges may
repeat, so on a cyclic graph every walk within the repeat bounds is counted.
A group with no matching paths gets no count. If you select the group’s keys
together with the count, its count shows as empty, not 0. Use | 0 to get a
0 instead.
Performance: The paths are counted without being enumerated: computing the
counts is polynomial in the size of the graph, even when the number of paths is
exponential. Use this to check the size of a result before calling AllPaths.paths.
The count itself can exceed the 128-bit integer range (2^127 - 1), which
raises a numeric overflow error rather than returning a wrong count.