Oihana PHP Arango

edges

Table of Contents

Functions

assertEdges()  : void
Ensures that a given value is an instance of {@see Edges}.
buildEdgeCountVariable()  : string|null
Generates a string of multiple AQL 'LET' statements for calculate the number of edges of a specific document.
buildEdgeSubquery()  : string
Builds the inner AQL edge traversal sub-query — everything an edge `LET` wraps, already enclosed in parentheses but WITHOUT the leading `LET name =`.
buildEdgeVariable()  : string
Builds a single AQL 'LET' subquery string for a specific edge relation.
buildEdgesVariables()  : string
Generates a string of multiple AQL 'LET' statements for all defined edge variables.
buildPolymorphicEdgeVariable()  : string
Builds a single AQL 'LET' subquery for a *polymorphic* edge — an edge whose traversed collection is chosen at query time from a discriminator field of the start vertex (the parent document).
edgeTraversalOptions()  : array<string|int, mixed>
The traversal options every edge relation is walked with — breadth-first, and each vertex visited **once globally**.
getEdges()  : Edges|null
Retrieves an {@see Edges} instance from various types of input definitions.
resolveEdgeContext()  : Edges, 1: string, 2: string}
Resolves the common edge-traversal context shared by the edge variable builders.
resolveEdgeDepthRange()  : array{0: int|null, 1: int|null}
Resolves the traversal depth range declared by an edge definition — the `[ $minDepth , $maxDepth ]` pair handed to {@see \oihana\arango\db\operations\aqlTraversal()}.
resolveEdges()  : void
Resolves and initializes internal edge model definitions from a dependency container.
resolveEdgeVertexScope()  : array{0: string|null, 1: string|null}
Compiles the **row scope** an edge definition declares over the vertices it traverses — the `[ $filter , $prune ]` pair, both already AQL predicate strings targeting `$vertexRef`, or `null` when nothing is declared.
sortEdgeVariable()  : string
Generates the internal AQL 'SORT' clause for an edge variable subquery.

Functions

assertEdges()

Ensures that a given value is an instance of {@see Edges}.

assertEdges(mixed $value) : void

This helper function acts as a runtime assertion to validate type safety. If the provided value is not an instance of Edges, an UnexpectedValueException is thrown with a descriptive message.

This is especially useful when handling dynamically typed data or container-resolved dependencies, where you want to enforce strict model integrity.

Parameters
$value : mixed

The value to assert as an Edges instance.

Tags
throws
UnexpectedValueException

If the provided value is not an instance of Edges.

example
use oihana\arango\models\helpers\assertEdges;
use oihana\arango\models\Edges;

$edges = new Edges();

// ✅ Valid: no exception thrown
assertEdges( $edges );

// ❌ Invalid: throws UnexpectedValueException
assertEdges( 'not an edges instance' );
// → UnexpectedValueException: The value property must be an instance of Edges.
author

Marc Alcaraz (eKameleon)

version
1.0.0

buildEdgeCountVariable()

Generates a string of multiple AQL 'LET' statements for calculate the number of edges of a specific document.

buildEdgeCountVariable(string|null $name[, array<string|int, mixed> $definition = [] ][, string $startVertex = AQL::DOC ][, ContainerInterface|null $container = null ]) : string|null

The count must answer the same question as the list. A count and a Filter::EDGES projection normally share one definition — the registry's string shortcut ('descendantsCount' => 'descendants') is the idiomatic way to say so — therefore every part of that declaration shaping which vertices are walked has to be read here exactly as buildEdgeSubquery() reads it. Three did not use to be, each producing a number the rows contradicted:

Declaration List Count, before
AQL::MAX_DEPTH => 5 over a ─┬─ b ── c / └─ e ── f [ b , c , e , f ] → 4 2 (direct children only)
depth 1 with a duplicated a → c edge [ b , c ] → 2 3 (counted twice)
1..5 over the diamond a → b → d / a → c → d [ b , c , d ] → 3 6

All three are now read through the shared helpers — resolveEdgeDepthRange(), resolveEdgeVertexScope() and edgeTraversalOptions() — so the count and the list cannot drift again. AQL::WHERE filters the counted loop and AQL::PRUNE stops it, both compiled against the inner vertex.

Nothing is emitted for a key that is not declared, so a definition without depth, scope or prune produces the historical single-level count — plus the traversal options, which is the one intentional change to the emitted AQL of an existing definition (and the one that makes a duplicated edge stop being counted twice).

Parameters
$name : string|null
$definition : array<string|int, mixed> = []
$startVertex : string = AQL::DOC
$container : ContainerInterface|null = null
Tags
throws
ContainerExceptionInterface
NotFoundExceptionInterface
ReflectionException
BindException
ConstantException
UnexpectedValueException

If AQL::MIN_DEPTH is declared without AQL::MAX_DEPTH, or AQL::PRUNE => true has no AQL::WHERE to negate.

UnsupportedOperationException

If an AQL::WHERE / AQL::PRUNE condition descriptor is malformed.

ValidationException

If an AQL::WHERE / AQL::PRUNE condition attribute name is unsafe.

Return values
string|null

buildEdgeSubquery()

Builds the inner AQL edge traversal sub-query — everything an edge `LET` wraps, already enclosed in parentheses but WITHOUT the leading `LET name =`.

buildEdgeSubquery(string|null $name[, array<string|int, mixed> $definition = [] ][, string $startVertex = AQL::DOC ][, ContainerInterface|null $container = null ][, array<string|int, mixed> $init = [] ][, array<string|int, mixed> $extraConditions = [] ]) : string

The returned string is the parenthesized traversal:

( FOR vertex, edge IN OUTBOUND doc edge_collection [<nested LETs>] [FILTER …] [SORT …] RETURN … )

buildEdgeVariable() prefixes it with LET name = for a regular edge, while buildPolymorphicEdgeVariable() wraps several such sub-queries into a single APPEND( ( … ) , ( … ) ) array so the traversed edge collection can vary with a discriminator field of the start vertex.

Extracting this body from buildEdgeVariable() lets a polymorphic edge reuse the whole traversal machinery (direction, depth, path metadata, skinning, nested edges / joins, definition-level gating) per branch. The only addition over the historical logic is $extraConditions: a list of ready-made AQL predicates (typically the discriminator guard on the start vertex) emitted as a FILTER right after the traversal. When empty, no FILTER is emitted, so the output is byte-for-byte identical to the legacy edge sub-query.

A definition may also declare AQL::WHERE — a condition in the Field::WHEN grammar, compiled against the traversed vertex and appended to $extraConditions. It restricts WHICH vertices the relation projects, wherever the definition is used, so a consumer masking part of a collection is not contradicted by the relation of a served document:

( FOR vertex, edge IN OUTBOUND doc coll FILTER vertex.id NOT IN @hiddenTerms … )

Its value may hold an aqlBindRef(), so the retained set is decided at query time; the contract is the one Field::WHERE already carries on a Filter::MAP (a bind bound to [] retains nothing, an absent bind fails the query — never "no filter"). It composes with the polymorphic guard rather than replacing it, and is orthogonal to AQL::REQUIRES / Field::REQUIRES, which decide whether the relation is projected at all.

AQL::WHERE filters the traversal's OUTPUT; on a ranged relation (AQL::MAX_DEPTH) the walk still descends through a masked vertex, so its descendants keep being projected. AQL::PRUNE stops the walk itself — true reuses the AQL::WHERE predicate negated ("hide it and its descent"), or a condition of its own when stopping is not hiding. The two are emitted together because PRUNE stops after visiting: the vertex it stops on is still returned unless the FILTER removes it.

Parameters
$name : string|null

The logical name of the relation (used to skin the projection).

$definition : array<string|int, mixed> = []

Configuration array for the traversal — same keys as buildEdgeVariable() (AQL::MODEL, AQL::DIRECTION, AQL::EDGES, AQL::JOINS, AQL::SKIN, AQL::MAX_DEPTH, AQL::WITH_PATH, AQL::WHERE, AQL::PRUNE, Arango::PROPERTY, …).

$startVertex : string = AQL::DOC

The AQL variable name of the starting vertex (default 'doc').

$container : ContainerInterface|null = null

The DI container used to resolve models.

$init : array<string|int, mixed> = []

Optional associative array used for variable initialization.

$extraConditions : array<string|int, mixed> = []

Ready-made AQL predicate strings emitted as a FILTER after the traversal (e.g. the discriminator guard of a polymorphic edge). Empty → no FILTER emitted (byte-identical output).

Tags
throws
Exception

If the traversal direction is invalid.

ContainerExceptionInterface

If the Edges model cannot be resolved from the container.

NotFoundExceptionInterface

If the Edges model cannot be resolved from the container.

ReflectionException
UnexpectedValueException

If $name is empty, the model is invalid, the collection is not set, or AQL::PRUNE => true has no AQL::WHERE condition to negate.

UnsupportedOperationException

If an AQL::WHERE / AQL::PRUNE condition descriptor is malformed.

ValidationException

If an AQL::WHERE / AQL::PRUNE condition attribute name is unsafe.

Return values
string

The parenthesized traversal sub-query (no leading LET name =).

buildEdgeVariable()

Builds a single AQL 'LET' subquery string for a specific edge relation.

buildEdgeVariable(string|null $name[, array<string|int, mixed> $definition = [] ][, string $startVertex = AQL::DOC ][, ContainerInterface|null $container = null ][, array<string|int, mixed> $init = [] ]) : string

This method generates a complete traversal subquery, enclosed in parentheses, which is assigned to a 'LET' variable. It handles direction, filtering, sorting, and shaping of the results.

The traversal body itself is produced by buildEdgeSubquery(); this wrapper only resolves the LET variable name and prefixes the body.

Example output: LET myFriends = ( FOR v, e IN OUTBOUND 'users/123' friends_edge ... RETURN v.name )

Parameters
$name : string|null

The logical name for this variable (e.g., 'friends', 'comments'). This is used as the AQL 'LET' variable name.

$definition : array<string|int, mixed> = []

Configuration array for the traversal. Expected keys:

  • AQL::MODEL: (string) The class name of the Edges model.
  • AQL::DIRECTION: (string|null) Traversal direction (OUTBOUND, INBOUND).
  • AQL::UNIQUE: (string|null) Optional AQL variable name, overrides $name.
  • AQL::EDGES: (array) Further edge definitions for nested queries.
  • AQL::JOINS: (array) Join definitions for the target model.
  • AQL::SKIN: (string|null) A 'skin' name to select specific fields.
  • AQL::SORT: (string|array|null) Sort definition (see getSortEdgeVariableExpression).
  • Arango::SOURCE: (string|null) Optional absolute path, read from the start vertex, holding the traversal start-vertex _id — the traversal then departs from doc.<source> instead of doc. The value MUST be a full document _id (e.g. providers/123), not a bare _key.
$startVertex : string = AQL::DOC

The AQL variable name of the starting vertex (default 'doc').

$container : ContainerInterface|null = null

The DI Container reference.

$init : array<string|int, mixed> = []

Optional associative array definitions.

Tags
throws
Exception

If Traversal direction is invalid.

ContainerExceptionInterface

If the Edges model cannot be resolved from the container.

NotFoundExceptionInterface

If the Edges model cannot be resolved from the container.

ReflectionException
UnexpectedValueException

If $name is empty, the model is invalid, or the collection is not set.

Return values
string

The complete AQL 'LET' statement.

buildEdgesVariables()

Generates a string of multiple AQL 'LET' statements for all defined edge variables.

buildEdgesVariables([array<string|int, mixed> &$variables = [] ][, array<string|int, mixed> $definitions = [] ][, string $startVertex = AQL::DOC ][, ContainerInterface|null $container = null ][, array<string|int, mixed> $init = [] ]) : string

This is a convenience method that iterates over a list of definitions and calls getEdgeVariable() for each one, concatenating the results.

Definition-level gating: a definition declaring AQL::REQUIRES that the request-scoped authorizer denies is skipped — its LET is not emitted.

Parameters
$variables : array<string|int, mixed> = []

The variables list reference to fill.

$definitions : array<string|int, mixed> = []

An associative array of edge definitions [ $name => $definition ].

$startVertex : string = AQL::DOC

The default AQL document reference (start vertex) for all traversals.

$container : ContainerInterface|null = null

The DI Container reference.

$init : array<string|int, mixed> = []

Optional associative array definition.

Tags
throws
ContainerExceptionInterface

| NotFoundExceptionInterface

ReflectionException
Exception
Return values
string

A string containing all generated AQL 'LET' statements, or an empty string if none.

buildPolymorphicEdgeVariable()

Builds a single AQL 'LET' subquery for a *polymorphic* edge — an edge whose traversed collection is chosen at query time from a discriminator field of the start vertex (the parent document).

buildPolymorphicEdgeVariable(string|null $name[, array<string|int, mixed> $definition = [] ][, string $startVertex = AQL::DOC ][, ContainerInterface|null $container = null ][, array<string|int, mixed> $init = [] ]) : string

The whole branch machinery (guarding, per-branch permission gating, the FALLBACK branch, the APPEND combine) lives in the shared buildPolymorphicRelationVariable(); this function only supplies the per-branch builder, which delegates to buildEdgeSubquery() (already a parenthesized traversal). Each branch is a full edge definition, so it may declare its own AQL::DIRECTION, AQL::MAX_DEPTH, etc.

The resulting LET always holds an array — exactly like a regular edge — so the projection layer (aqlFieldObject()) unwraps it with FIRST() for a Filter::EDGE or keeps the whole array for a Filter::EDGES.

Example output (two branches):

LET rel = APPEND(
  ( FOR vertex, edge IN OUTBOUND doc warehouse_edges
      FILTER doc.kind == "warehouse"
      RETURN { _key: vertex._key, name: vertex.name } ) ,
  ( FOR vertex, edge IN OUTBOUND doc company_edges
      FILTER doc.kind == "company"
      RETURN { _key: vertex._key, name: vertex.name } )
)
Parameters
$name : string|null

The edge field name — also the default LET variable name.

$definition : array<string|int, mixed> = []

The polymorphic edge definition. Keys:

  • Arango::DISCRIMINATOR (string) Start-vertex field path deciding the branch (required).
  • Arango::MAP (array) Non-empty type => edge-definition table (required).
  • Arango::UNIQUE (string|null) Optional LET variable name, overrides $name.
  • Arango::SOURCE (string|null) Optional absolute path holding the traversal start-vertex _id; the traversal then departs from doc.<source> while the discriminator STAYS resolved on the parent document (doc.<discriminator>).
  • Arango::FALLBACK (array|null) Edge definition for unmatched discriminator values (null = none).
$startVertex : string = AQL::DOC

The AQL variable name of the start vertex.

$container : ContainerInterface|null = null

Optional DI container used to resolve branch models.

$init : array<string|int, mixed> = []

Optional associative array used for variable initialization.

Tags
throws
Exception

If a branch traversal cannot be built.

ContainerExceptionInterface

If a branch model cannot be resolved from the container.

NotFoundExceptionInterface

If a branch model cannot be found in the container.

ReflectionException
UnexpectedValueException

If $name is empty, or the definition lacks a non-empty Arango::MAP / Arango::DISCRIMINATOR.

since
1.0.0
author

Marc Alcaraz

Return values
string

The complete AQL 'LET' statement.

edgeTraversalOptions()

The traversal options every edge relation is walked with — breadth-first, and each vertex visited **once globally**.

edgeTraversalOptions() : array<string|int, mixed>

uniqueVertices: global is not cosmetic, it decides how many rows come back. Two shapes make a vertex reachable more than once: a diamond (a → b → d plus a → c → d) and a plainly duplicated edge (a → c created twice). ArangoDB's default (uniqueVertices: none) yields such a vertex once per path.

The list always passed these options; the count passed none — so the two disagreed on the same data, measured live on the shapes above:

Declaration List Count, before
depth 1, one duplicated edge [ b , c ] → 2 3
1..5 over the diamond [ b , c , d ] → 3 6

Both builders now read the options here, so a count can no longer over-count rows the list de-duplicated.

Tags
since
1.0.0
author

Marc Alcaraz

Return values
array<string|int, mixed>

The AQL::OPTIONS payload of an edge traversal.

getEdges()

Retrieves an {@see Edges} instance from various types of input definitions.

getEdges([array<string|int, mixed>|string|Edges|null $definition = null ][, ContainerInterface|null $container = null ][, string $key = Arango::EDGES ][, Edges|null $default = null ]) : Edges|null

This helper function resolves an Edges object from a direct instance, an array definition, a service name within a PSR-11 container, or falls back to a provided default value.

Behavior:

  • If $definition is an Edges instance, it is returned as-is.
  • If $definition is an array, the function looks for the Arango::EDGES key.
  • If $definition is a non-empty string and $container contains a service with that name, the corresponding service is fetched.
  • If none of the above conditions are met, the $default value is returned.
Parameters
$definition : array<string|int, mixed>|string|Edges|null = null

Input definition that may represent an Edges instance, an associative array containing one, or a container service name.

$container : ContainerInterface|null = null

Optional PSR-11 container used to resolve string service names.

$key : string = Arango::EDGES

Array key to look for when $definition is an array

$default : Edges|null = null

Default Edges instance to return if resolution fails.

Tags
throws
ContainerExceptionInterface
NotFoundExceptionInterface
example
use oihana\arango\models\helpers\getEdges;
use oihana\arango\models\Edges;
use oihana\arango\enums\Arango;
use Psr\Container\ContainerInterface;

$edges = new Edges(['_from' => 'users/1', '_to' => 'posts/5']);

// Example 1: Direct instance
$result = getEdges($edges);
// → returns the same $edges instance

// Example 2: From array definition
$result = getEdges([Arango::EDGES => $edges]);
// → returns the $edges instance from the array

// Example 3: From container service name
$container->method('has')->willReturn(true);
$container->method('get')->willReturn($edges);
$result = getEdges('my.edges.service', $container);
// → returns the $edges instance resolved from the container

// Example 4: With default fallback
$default = new Edges(['_from' => 'fallback/A', '_to' => 'fallback/B']);
$result = getEdges(null, null, $default);
// → returns $default
author

Marc Alcaraz (eKameleon)

version
1.0.0
Return values
Edges|null

Returns the resolved Edges instance or the default value if not found.

resolveEdgeContext()

Resolves the common edge-traversal context shared by the edge variable builders.

resolveEdgeContext([array<string|int, mixed> $definition = [] ][, ContainerInterface|null $container = null ]) : Edges, 1: string, 2: string}

This helper centralizes the preamble duplicated by buildEdgeVariable() and buildEdgeCountVariable(): it resolves the Edges model from the definition (via getEdges()), validates it, reads its non-empty collection name and normalizes the traversal direction.

Parameters
$definition : array<string|int, mixed> = []

The relation definition. Expected keys:

  • AQL::MODEL : the Edges model (instance, array or container id).
  • AQL::DIRECTION : the traversal direction (defaults to Traversal::OUTBOUND).
$container : ContainerInterface|null = null

Optional DI container used to resolve the model.

Tags
throws
ContainerExceptionInterface
NotFoundExceptionInterface
UnexpectedValueException

If the model is not an Edges instance or its collection is empty.

Return values
Edges, 1: string, 2: string}

A triplet [ $model , $edgeCollection , $direction ].

resolveEdgeDepthRange()

Resolves the traversal depth range declared by an edge definition — the `[ $minDepth , $maxDepth ]` pair handed to {@see \oihana\arango\db\operations\aqlTraversal()}.

resolveEdgeDepthRange(array<string|int, mixed> $definition) : array{0: int|null, 1: int|null}

A self-referential relation (a thesaurus, a category tree, an org chart) can project several levels in a single traversal through AQL::MAX_DEPTH. The rules:

  • Neither declared → [ null , null ], the traversal stays at depth 1 and the emitted AQL is byte-for-byte the un-ranged one.
  • AQL::MAX_DEPTH alone defaults the lower bound to 1 — the natural 1..N.
  • AQL::MIN_DEPTH alone is refused. ArangoDB requires a bounded range, and an unbounded traversal over a self-referential edge risks a runaway cycle.

This lives in its own helper because the list and the count must read the declaration the same way. They did not: buildEdgeCountVariable() ignored the range entirely, so a definition declaring AQL::MAX_DEPTH => 5 produced a list of the whole descent beside a count of the direct children — measured live as 4 rows under a count saying 2. A shared door makes that divergence impossible to reintroduce, including the refusal rule.

Parameters
$definition : array<string|int, mixed>

The edge definition (reads AQL::MIN_DEPTH / AQL::MAX_DEPTH).

Tags
throws
UnexpectedValueException

If AQL::MIN_DEPTH is declared without AQL::MAX_DEPTH.

since
1.0.0
author

Marc Alcaraz

Return values
array{0: int|null, 1: int|null}

The [ $minDepth , $maxDepth ] pair.

resolveEdges()

Resolves and initializes internal edge model definitions from a dependency container.

resolveEdges([array<string|int, mixed>|null &$edges = [] ][, Container|null $container = null ]) : void

This helper ensures that all edge-related dependencies defined in the model configuration (under AQL::EDGES) are properly instantiated in the DI container.

It supports multiple edge definition formats:

  • Associative arrays mapping a property to its edge configuration.
  • Indexed arrays containing simple string references to container entries.
  • The special key AQL::RESOLVE (or __resolve__) for one-shot dependency resolution, used to pre-load edge models in memory without explicit configuration.

Typical usage:

resolveEdges( $model[AQL::EDGES] ?? [], $container );

Behavior:

  • Each string identifier found in indexed or AQL::RESOLVE arrays is resolved through the container.
  • Associative definitions are analyzed to resolve their AQL::MODEL entry if it refers to a container ID.
  • Existing Edges instances are left untouched.
Parameters
$edges : array<string|int, mixed>|null = []

The array of edge definitions to resolve (may be associative or indexed).

$container : Container|null = null

The DI container used to resolve Edges references.

Tags
throws
DependencyException

If a dependency cannot be loaded by the DI container.

NotFoundException

If a referenced container entry is not found.

ContainerExceptionInterface

If the container encounters a general error while resolving.

NotFoundExceptionInterface

If a referenced entry is missing in a PSR-11 container.

resolveEdgeVertexScope()

Compiles the **row scope** an edge definition declares over the vertices it traverses — the `[ $filter , $prune ]` pair, both already AQL predicate strings targeting `$vertexRef`, or `null` when nothing is declared.

resolveEdgeVertexScope(array<string|int, mixed> $definition, string $vertexRef) : array{0: string|null, 1: string|null}

Two keys, answering two different questions:

  • AQL::WHERE — WHICH vertices the relation yields. Compiled from the Field::WHEN grammar, so a value may hold an aqlBindRef() and the retained set is decided at query time (a bind bound to [] retains nothing, an absent bind fails the query — never "no filter"). Emitted as a FILTER after the traversal.
  • AQL::PRUNE — whether the walk STOPS there. A FILTER only filters the traversal's output: on a ranged relation the walk still descends through a masked vertex, so its descendants keep being projected. true reuses the AQL::WHERE predicate negated ("hide it and its descent"); a condition of its own covers the case where stopping is not hiding. A condition is compiled rather than read as a boolean — anything written there is truthy, so it would otherwise be silently swapped for the negated AQL::WHERE. false means OFF, like an absent key, so a AQL::PRUNE => $flag toggle works both ways.

The two are emitted together and neither replaces the other: PRUNE stops the walk after visiting, so the vertex it stops on is still returned unless the FILTER removes it.

This lives in its own helper because the list and the count must read the declaration the same way — a count that scoped differently from the list would announce a number the rows contradict, which is the whole class of bug these keys exist to close.

Parameters
$definition : array<string|int, mixed>

The edge definition (reads AQL::WHERE / AQL::PRUNE).

$vertexRef : string

The AQL variable of the traversed vertex both predicates target.

Tags
throws
UnexpectedValueException

If AQL::PRUNE => true has no AQL::WHERE to negate.

UnsupportedOperationException

If a condition descriptor is malformed.

ValidationException

If a condition attribute name is unsafe.

since
1.0.0
author

Marc Alcaraz

Return values
array{0: string|null, 1: string|null}

The [ $filter , $prune ] predicates.

sortEdgeVariable()

Generates the internal AQL 'SORT' clause for an edge variable subquery.

sortEdgeVariable(array<string|int, mixed>|string|null $definition[, string $vertexRef = AQL::VERTEX ][, string $edgeRef = AQL::EDGE ][, string $defaultProperty = Schema::CREATED ]) : string

This helper method interprets a flexible sort definition and constructs the appropriate AQL 'SORT' expression.

  • If $definition is an array: Looks for AQL::SORT (property) and AQL::ORDER (ASC/DESC) and sorts by the vertex property.
  • If $definition is a string (legacy): Sorts by that string as the property on the vertex in ASC order.
  • If $definition is null (or AQL::SORT is not set in the array): Sorts by the $defaultProperty (e.g., 'created') on the edge in DESC order.
Parameters
$definition : array<string|int, mixed>|string|null

The sort configuration. Typically the $definition array from getEdgeVariable.

$vertexRef : string = AQL::VERTEX

The internal AQL vertex variable reference.

$edgeRef : string = AQL::EDGE

The internal AQL edge variable reference.

$defaultProperty : string = Schema::CREATED

The fallback property to sort by (default: 'created').

Tags
example

Assume the following constant values for the examples:

  • AQL::SORT = 'sort'
  • AQL::ORDER = 'order'
  • Order::DESC = 'DESC'
  • Order::ASC = 'ASC'
  • Schema::CREATED = 'created'
  • AQL::EDGE_PREFIX = 'e_'
  • AQL::VERTEX_PREFIX = 'v_'

Case 1: Default sort (null definition)

Sorts by 'created' on the edge (e_) in DESC order.

echo sortEdgeVariable( null , 'friends_rel');
// Output: "SORT e_friends_rel.created DESC"

Case 2: Legacy string sort (string definition)

Sorts by 'name' on the vertex (v_) in ASC order.

echo sortEdgeVariable( 'name' , 'friends_rel');
// Output: "SORT v_friends_rel.name ASC"

Case 3: Array definition (DESC)

Sorts by 'age' on the vertex (v_) in DESC order.

$definition =
[
    AQL::SORT  => 'age',
    AQL::ORDER => Order::DESC
];
echo sortEdgeVariable( $definition, 'friends_rel' );
// Output: "SORT v_friends_rel.age DESC"

Case 4: Array definition (ASC)

Sorts by 'lastName' on the vertex (v_) in ASC order.

$definition = [ AQL::SORT => 'lastName' ]; // AQL::ORDER defaults to ASC
echo sortEdgeVariable( $definition , 'friends_rel');
// Output: "SORT v_friends_rel.lastName ASC"

Case 5: Array definition missing 'sort' key ---

Falls back to default sort (Case 1).

$def5 = [ AQL::ORDER => Order::DESC ];
echo sortEdgeVariable($def5, 'friends_rel');
// Output: "SORT e_friends_rel.created DESC"
* ```
Return values
string

The generated AQL 'SORT' clause (e.g., "SORT v_myVar_collectionName.name ASC").

On this page

Search results