Oihana PHP Arango

FieldsTrait uses trait:short, trait:short, trait:short

Trait FieldsTrait

Provides functionality to define, normalize, and prepare AQL query fields for ArangoDB models, including support for:

  • Skins (full/minimal/custom)
  • Edges and joins
  • Subfields for DOCUMENT or MAP filters
  • Unique keys for special fields
  • Optional filtering of fields using the $in parameter

Usage overview:

// Initialize fields definitions
$model->initializeFields([
    FieldsTrait::FIELDS => [
        'name' => Filter::DEFAULT,
        'status' => Filter::BOOL,
        'permissions' => [ Field::FILTER => Filter::EDGES, Field::SKINS => ['full'] ]
    ]
]);

// Prepare query fields for a skin or subset
$queryFields = $model->prepareQueryFields(
    fields: null,         // use default $this->fields if null
    skin: 'full',         // optional skin filter
    parentKey: null,      // optional parent key for unique key generation
    in: ['name','status'] // optional list of field keys to include; string, array, or null
);

// Generate an AQL query fragment with LET or RETURN
$aql = $model->returnFields([
    Arango::QUERY_FIELDS => $queryFields,
    Arango::DOC_REF      => 'doc',
    Arango::SKIN         => 'full'
]);

Important behaviors:

  • $fields in prepareQueryFields(): If null, uses $this->fields. You can pass a custom array of field definitions.
  • $skin: Filters fields based on their Field::SKINS property using matchesSkin(). The skin is propagated to the nested sub-fields of WRAP / DOCUMENT / MAP definitions, so a Field::SKINS marker is honored at every depth. When the skin removes every declared sub-field of a structural field, the field itself is dropped from the projection (key absent).
  • $in: If null → all fields are included. If array → only keys present in the array are included. If string → treated as a single key, or a comma-separated list of keys (split and trimmed). If empty string or empty array → no fields are returned (prepareQueryFields() returns null).
  • Normalization: Each field is converted to an array. Every declarative Field::* key is preserved as-is:
    • Field::FILTER, Field::ALTERS, Field::DEFAULT, Field::ELSE, Field::FORMAT, Field::NAME, Field::PATH, Field::PATHS, Field::PROPERTY, Field::QUOTED, Field::RAW, Field::REQUIRES, Field::SELF_REQUIRES, Field::SCOPE, Field::WHEN, Field::WHERE (see self::NORMALIZED_MARKERS)
    • Field::FIELDS for DOCUMENT or MAP subfields
    • Field::UNIQUE for unique key generation for edges, joins, or unique names
  • returnFields(): Generates AQL document expressions with optional LET statements. Handles:
    • Char::ASTERISK for all fields if no queryFields are provided
    • Edges and joins automatically
    • Prepared query fields from prepareQueryFields()
    • Optional variable assignment ($isVariable = true)

Notes:

  • To generate AQL fragments, the trait relies on helper functions like
    • aqlDocument()
    • aqlFields()
    • buildVariables()
    • buildEdgesVariables()
    • buildJoinVariables()
  • Edge, join, and unique field keys are suffixed automatically to prevent collisions.
Tags
author

Marc Alcaraz (eKameleon)

since
1.0.0

Table of Contents

Constants

EDGE_SUFFIX  : string = '_e'
The suffix used for edge fields in queries.
EDGES  : string = 'edges'
The 'edges' parameter key.
FIELDS  : string = 'fields'
The 'fields' key for initialization arrays.
JOIN_SUFFIX  : string = '_j'
The suffix used for join fields in queries.
JOINS  : string = 'joins'
The 'joins' parameter key.
UNIQUE_SUFFIX  : string = '_u'
The suffix used for unique fields in queries.
NORMALIZED_MARKERS  : array<string|int, mixed> = [\oihana\arango\enums\Field::ALTERS, \oihana\ar...
The scalar `Field::` markers copied **verbatim** from the raw field options into the normalized definition produced by {@see normalizeFieldDefinition()}.

Properties

$collection  : string|null
The default collection name.
$edges  : array<string|int, mixed>|null
The list of all edges definitions to generates the complex edge attributes or resolve and create the Edges dependencies in the DI Container.
$fields  : array<string, mixed>
The fields definitions to return in get/list methods.
$indexes  : array<string|int, mixed>|null
The declared indexes of the collection (the `AQL::INDEXES` list of {@see IndexOptions} or raw definitions). Retained at initialization — whether the lazy provisioning ran or not — so the declaration can be compared with the server later ({@see DoctorTrait::diagnose()}).
$joins  : array<string|int, mixed>|null
The list of all joins definitions to generates basic relations with documents.
$skinFields  : array<string, array<string, mixed>>
Optional per-skin alternative projections for the model's own fields.
$arangodb  : ArangoDB|null
The ArangoDB database reference.
$type  : int
Indicates the type of the collection when is created (document or edge).

Methods

analyzerExists()  : bool
Checks if an analyzer exists on the server (built-in analyzers are always reported).
collectionCreate()  : bool
Creates a new collection if not exist.
collectionDrop()  : bool
Drops a collection if exist.
collectionExists()  : bool
Check if collection exists
collectionRename()  : bool
Renames a collection if exist.
collectionTruncate()  : bool
Truncate a collection if exist.
createIndex()  : array<string|int, mixed>|null
Creates an index on a collection on the server.
debugQuery()  : void
Debug the passed-in query and binds variables.
explain()  : ExplainResult
Explains an AQL query — returns the optimizer's execution plan as a typed {@see ExplainResult} (rules applied, collections, estimated cost, indexes actually used) **without executing the query**.
foundRows()  : int
For a SELECT with a LIMIT clause, returns the number of rows that would be returned were there no LIMIT clause.
getDatabase()  : ArangoDB
Returns the ArangoDB database singleton reference.
getDocuments()  : array<string|int, mixed>
Prepare, execute and returns an array of all documents with the passed-in AQL query.
getExtra()  : array<string|int, mixed>
Returns the AQL current extra datas.
getFirstResult()  : mixed
Prepare, execute and returns the first result of the passed-in AQL query.
getObject()  : object|null
Prepare, execute and returns an object with the passed-in AQL query.
getProfile()  : ProfileResult
Returns the typed profile of the last profiled query run (per-phase timings, {@see ExecutionStats}, warnings).
getResult()  : array<string|int, mixed>|null
Prepare, execute and returns an array with the passed-in AQL query.
getStats()  : ExecutionStats
Returns the typed execution statistics of the last query (scanned / filtered / time / memory …). Most meaningful right after a profiled `list()` / `get()` (see {@see Arango::PROFILE}).
initializeCollection()  : static
Sets the internal collection reference.
initializeDatabase()  : static
Set the internal arangoDB reference.
initializeEdges()  : static
Initialize the 'edges' definitions.
initializeFields()  : static
Initialize fields definitions from an associative array.
initializeIndexes()  : static
Sets the declared indexes of the collection from the init definition, normalizing a single {@see IndexOptions} value to a one-element list (a raw array always stays the index list) — so every consumer sees a plain `IndexOptions[]`: the {@see initializeCollection()} lazy provisioning and the {@see DoctorTrait} diagnose/repair diffs.
initializeJoins()  : static
Initialize the 'joins' definitions.
initializeSkinFields()  : static
Initialize the per-skin projections registry from an associative array.
prepareAndExecute()  : static
Prepare and execute an ArangoDB AQL query.
prepareQueryFields()  : array<string, array<string|int, mixed>>|null
Prepares query fields based on internal definitions and optional skin filter.
registerProperty()  : void
Register a specific dynamic property in the binds and values collection to generates a query.
releaseEdges()  : static
Releases the 'edges' definitions.
releasesJoins()  : static
Releases the 'joins' definitions.
returnFields()  : string
Generates an AQL document expression or LET statement with the selected fields.
streamDocuments()  : Generator<string|int, mixed>
Prepare, execute and returns a generator of documents with the passed-in AQL query.
viewCreate()  : bool
Creates an `arangosearch` View if it does not already exist.
viewExists()  : bool
Checks if a View exists.
firstRowAsArray()  : array<string|int, mixed>
Runs a single-row aggregate query and normalizes its result to an array.
profileOptions()  : array<string|int, mixed>
Merges the cursor `profile` option into `$options` when the `$init` array requests profiling via {@see Arango::PROFILE} (`true` → profile level 2, or an explicit integer level). Returns `$options` unchanged otherwise.
collectOptionalBindNames()  : array<int, string>
Collects every {@see AqlBindReference} name declared anywhere in one or more declaration trees — the projections (`$fields` / `$skinFields`) **and** the relation registries (`$edges` / `$joins`), typically inside a `Field::WHERE` / `Field::WHEN` condition. These are the *optional* binds : a skin (or an explicit `?fields`) can drop the carrying field — or the whole relation — from the projection, so the declared bind may not reach the final query text.
filterFieldsBySkin()  : array<string, mixed>
Filters fields based on an optional skin.
generateUniqueKey()  : string|null
Generates a unique key for special filters like edges, joins, or unique names.
normalizeFieldDefinition()  : array<string, mixed>|null
Normalize a field definition into a structured array for queries.

Constants

EDGE_SUFFIX

The suffix used for edge fields in queries.

public string EDGE_SUFFIX = '_e'

EDGES

The 'edges' parameter key.

public string EDGES = 'edges'

FIELDS

The 'fields' key for initialization arrays.

public string FIELDS = 'fields'

JOIN_SUFFIX

The suffix used for join fields in queries.

public string JOIN_SUFFIX = '_j'

JOINS

The 'joins' parameter key.

public string JOINS = 'joins'

UNIQUE_SUFFIX

The suffix used for unique fields in queries.

public string UNIQUE_SUFFIX = '_u'

NORMALIZED_MARKERS

The scalar `Field::` markers copied **verbatim** from the raw field options into the normalized definition produced by {@see normalizeFieldDefinition()}.

private array<string|int, mixed> NORMALIZED_MARKERS = [\oihana\arango\enums\Field::ALTERS, \oihana\arango\enums\Field::DEFAULT, \oihana\arango\enums\Field::ELSE, \oihana\arango\enums\Field::FORMAT, \oihana\arango\enums\Field::NAME, \oihana\arango\enums\Field::NULLABLE, \oihana\arango\enums\Field::PATH, \oihana\arango\enums\Field::PATHS, \oihana\arango\enums\Field::PROPERTY, \oihana\arango\enums\Field::QUOTED, \oihana\arango\enums\Field::RAW, \oihana\arango\enums\Field::REQUIRES, \oihana\arango\enums\Field::SELF_REQUIRES, \oihana\arango\enums\Field::SCOPE, \oihana\arango\enums\Field::WHEN, \oihana\arango\enums\Field::WHERE]

⚠️ Single source of truth — register every new marker here. A scalar Field:: marker absent from this list is silently stripped during projection normalization, so it never reaches the query builders nor the permission gates (this is exactly how Field::SELF_REQUIRES was first lost). The structural markers are built separately and must NOT be added here: Field::FILTER (seeded from the already-resolved filter), Field::FIELDS / Field::EDGES / Field::JOINS (sub-projections attached after the recursive walk), Field::UNIQUE (generated), and the skin buckets (AQL::SKIN_FIELDS).

Field::DEFAULT is intentionally kept even though it resolves to null (Field::DEFAULT === null), so the copy is byte-for-byte identical to the historical literal table.

Properties

$collection

The default collection name.

public string|null $collection

$edges

The list of all edges definitions to generates the complex edge attributes or resolve and create the Edges dependencies in the DI Container.

public array<string|int, mixed>|null $edges = null
Tags
example

1 - Use an associative array to manage the attributes with an Edges relation.

$documents = new Documents
([
    AQL::COLLECTION => Collections::PLACES ,
    AQL::DATABASE   => Databases::ARANGO ,
    AQL::SCHEMA     => Place::class ,
    AQL::EDGES      =>
    [
        Schema::ADDITIONAL_TYPE =>
        [
             AQL::MODEL => EdgesDefinition::PLACE_HAS_TYPE ,
        ]
        Schema::CONTAINED_IN_PLACE => // $to -> $from
        [
            AQL::MODEL     => EdgesDefinition::PLACE_CONTAINS_PLACE ,
            AQL::DIRECTION => Traversal::INBOUND ,
            AQL::SORT      => Prop::NAME ,
            AQL::ORDER     => Order::ASC ,
            AQL::SKIN      => Skin::DEFAULT
        ],
        Schema::CONTAINS_PLACE => // $from -> $to
        [
             AQL::MODEL  => EdgesDefinition::PLACE_CONTAINS_PLACE ,
             AQL::SORT  => Prop::NAME ,
             AQL::SKIN  => Skin::DEFAULT ,
             AQL::FIELDS => // custom fields
             [
                   Prop::_KEY     => Filter::DEFAULT  ,
                   Prop::NAME     => Filter::DEFAULT  ,
                   Prop::CREATED  => Filter::DATETIME ,
                   Prop::MODIFIED => Filter::DATETIME ,
             ]
        ]
        // Reference an other edges definition
        Schema::NUM_CONTAINS_PLACE => Schema::CONTAINS_PLACE
    ],
    AQL::FIELDS =>
    [
        Schema::_KEY               => Filter::DEFAULT ,
        Schema::NAME               => Filter::DEFAULT ,
        Schema::CREATED            => Filter::DATETIME ,
        Schema::MODIFIED           => Filter::DATETIME ,
        Schema::ADDITIONAL_TYPE    => Filter::EDGE ,
        Schema::CONTAINED_IN_PLACE => Filter::EDGES ,
        Schema::CONTAINS_PLACE     => Filter::EDGES ,
        Schema::NUM_CONTAINS_PLACE => Filter::EDGES_COUNT ,
    ]
]) ;

$places = $documents->list([ AQL::LIMIT => 0 ]) ;

echo( json_encode( $places , JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT ) ) ;

2 - Use an indexed array to resolves the Edges definition in the DI Container.

$documents = new Documents
([
    AQL::COLLECTION => Collections::PLACE_TYPES ,
    AQL::DATABASE   => Databases::ARANGO ,
    AQL::SCHEMA     => DefinedTerm::class ,
    AQL::EDGES      =>
    [
        EdgesDefinition::PLACE_HAS_TYPE ,
        // ... others Edges definitions
    ],
])

3 - Mix the Edges configurations and the Edges only resolving in the DI Container.

$documents = new Documents
([
    AQL::COLLECTION => Collections::PLACE_TYPES ,
    AQL::DATABASE   => Databases::ARANGO ,
    AQL::SCHEMA     => DefinedTerm::class ,
    AQL::EDGES      =>
    [
         AQL::RESOLVE =>
         [
              EdgesDefinition::PLACE_HAS_TYPE ,
              // ... others Edges definitions
         ] ,

    ],
    Schema::CONTAINS_PLACE =>
    [
        AQL::MODEL => EdgesDefinition::PLACE_CONTAINS_PLACE ,
    ]
])

$fields

The fields definitions to return in get/list methods.

public array<string, mixed> $fields = []

Keys are field names, values are either a Filter constant, a definition array, or null.

Tags
example
$model->fields =>
[
    Schema::ACTIVE                => Filter::BOOL ,
    Schema::WITH_STATUS           => Field::FILTER => Filter::DEFAULT ,
    Schema::ID                    => Filter::ID ,
    Schema::NAME                  => null , // Filter::DEFAULT ,
    Schema::URL                   => Filter::URL ,
    Schema::CREATED               => Filter::DATETIME ,
    Schema::MODIFIED              => [ Field::FILTER => Filter::DATETIME ] ,
    Schema::IMAGE                 => [ Field::FILTER => Filter::EDGE ] ,
    Schema::ALTERNATIVE_HEADLINE  => Filter::TRANSLATE ,
    Schema::ALTERNATE_NAME        => Filter::TRANSLATE ,
    Schema::DESCRIPTION           => Filter::TRANSLATE ,
    Schema::HEADLINE              => Filter::TRANSLATE ,
    Schema::SLOGAN                => Filter::TRANSLATE ,
    Schema::SCOPE_HAS_PERMISSION  => [ Field::FILTER => Filter::BOOL ] ,
    Schema::TOKEN_EXPIRATION      => [ Field::FILTER => Filter::INT  ] ,
    Schema::PERMISSIONS           => [ Field::FILTER => Filter::EDGES , Field::SKINS => [ Skin::FULL ] ]
    Schema::NUM_PERMISSIONS       => Field::FILTER => Filter::EDGES_COUNT
] ;

$indexes

The declared indexes of the collection (the `AQL::INDEXES` list of {@see IndexOptions} or raw definitions). Retained at initialization — whether the lazy provisioning ran or not — so the declaration can be compared with the server later ({@see DoctorTrait::diagnose()}).

public array<string|int, mixed>|null $indexes = null

$joins

The list of all joins definitions to generates basic relations with documents.

public array<string|int, mixed>|null $joins = null
Tags
example
$documents = new Documents
([
    AQL::JOINS =>
    [
         // each entry maps a local reference field to the related model joined on a key
         Schema::ADDITIONAL_TYPE => [ AQL::MODEL => 'placeTypes' , AQL::KEY => Schema::_KEY ] ,
         Schema::CONTAINS_PLACE  => [ AQL::MODEL => 'places'     , AQL::KEY => Schema::_KEY ] ,
    ],
    AQL::FIELDS =>
    [
        Schema::_KEY               => Filter::DEFAULT ,
        Schema::NAME               => Filter::DEFAULT ,
        Schema::CREATED            => Filter::DATETIME ,
        Schema::MODIFIED           => Filter::DATETIME ,
        Schema::ADDITIONAL_TYPE    => Filter::JOIN ,
        Schema::CONTAINS_PLACE     => Filter::JOINS ,
        Schema::NUM_CONTAINS_PLACE => Filter::JOINS_COUNT ,
    ]
]) ;

$places = $documents->list([ AQL::LIMIT => 0 ]) ;

echo( json_encode( $places , JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT ) ) ;

$skinFields

Optional per-skin alternative projections for the model's own fields.

public array<string, array<string, mixed>> $skinFields = []

A skin => fields table with the exact same semantics as the AQL::SKIN_FIELDS key of an edge/join definition : each bucket is a complete fields array (same shape as $fields), the resolution order is [$skin]['*']$fieldsnull, and the selected bucket fully replaces the others (no merging). An edge/join that declares no projection of its own inherits the target model's buckets, since it prepares the model fields with the request skin.

An empty registry (default) keeps the legacy single-projection behavior, byte-for-byte.

Tags
example
$model->skinFields =
[
    Skin::DEFAULT => [ Schema::NAME => Filter::DEFAULT ] ,
    Skin::FULL    => [ Schema::NAME => Filter::DEFAULT , Schema::ROLES => [ Field::FILTER => Filter::EDGES ] ] ,
] ;

$type

Indicates the type of the collection when is created (document or edge).

protected int $type

Methods

analyzerExists()

Checks if an analyzer exists on the server (built-in analyzers are always reported).

public analyzerExists(string $name) : bool
Parameters
$name : string

The name of the analyzer.

Return values
bool

collectionCreate()

Creates a new collection if not exist.

public collectionCreate(string $name[, array<string|int, mixed> $options = [] ]) : bool
Parameters
$name : string

The name of the new collection

$options : array<string|int, mixed> = []
  • an array of options.

Options are:

  • 'type' - 2 -> normal collection, 3 -> edge-collection
  • 'waitForSync' - if set to true, then all removal operations will instantly be synchronised to disk / If this is not specified, then the collection's default sync behavior will be applied.
  • 'isSystem' - false->user collection(default), true->system collection .
  • 'keyOptions' - key options to use.
  • 'distributeShardsLike' - name of prototype collection for identical sharding.
  • 'numberOfShards' - number of shards for the collection.
  • 'replicationFactor' - number of replicas to keep (default: 1).
  • 'writeConcern' - minimum number of replicas to be successful when writing (default: 1).
  • 'shardKeys' - array of shard key attributes.
  • 'shardingStrategy' - sharding strategy to use in cluster.
  • 'smartJoinAttribute' - attribute name for smart joins (if not shard key).
  • 'schema' - collection schema.
  • Return values
    bool

    Returns true if the new collection is created.

    collectionDrop()

    Drops a collection if exist.

    public collectionDrop(string $name) : bool
    Parameters
    $name : string

    The name of the new collection

    Return values
    bool

    Returns true if the new collection is dropped.

    collectionExists()

    Check if collection exists

    public collectionExists(string $name) : bool
    Parameters
    $name : string

    The name of the collection

    Return values
    bool

    collectionRename()

    Renames a collection if exist.

    public collectionRename(string $oldName, string $name) : bool
    Parameters
    $oldName : string

    The old name of the collection

    $name : string

    The new name of the collection

    Tags
    throws
    ArangoException
    Return values
    bool

    Returns true if the collection is renamed.

    collectionTruncate()

    Truncate a collection if exist.

    public collectionTruncate(string $name) : bool
    Parameters
    $name : string

    The name of the collection to truncate.

    Return values
    bool

    createIndex()

    Creates an index on a collection on the server.

    public createIndex(string|Collection $collection, array<string|int, mixed>|IndexOptions $indexOptions) : array<string|int, mixed>|null
    Parameters
    $collection : string|Collection

    Collection name or Collection client handle.

    $indexOptions : array<string|int, mixed>|IndexOptions

    An IndexOptions definition or an associative array of options for the index like array('type' => 'persistent', 'fields' => ['id','additionalType'], 'sparse' => false)

    Tags
    throws
    ReflectionException
    Return values
    array<string|int, mixed>|null

    The server response of the created index or null

    debugQuery()

    Debug the passed-in query and binds variables.

    public debugQuery(string $method, string $query, array<string|int, mixed>|null $binds) : void
    Parameters
    $method : string
    $query : string
    $binds : array<string|int, mixed>|null

    explain()

    Explains an AQL query — returns the optimizer's execution plan as a typed {@see ExplainResult} (rules applied, collections, estimated cost, indexes actually used) **without executing the query**.

    public explain(AqlQuery|string $query[, array<string, mixed> $bindVars = [] ][, array<string, mixed> $options = [] ]) : ExplainResult
    Parameters
    $query : AqlQuery|string

    The AQL query to explain.

    $bindVars : array<string, mixed> = []

    Bind variables (omit when $query is an AqlQuery).

    $options : array<string, mixed> = []

    Explain options (allPlans, optimizer.rules, …).

    Tags
    throws
    ArangoException
    Return values
    ExplainResult

    foundRows()

    For a SELECT with a LIMIT clause, returns the number of rows that would be returned were there no LIMIT clause.

    public foundRows() : int
    Return values
    int

    getDocuments()

    Prepare, execute and returns an array of all documents with the passed-in AQL query.

    public getDocuments(string $query[, array<string|int, mixed> $bindVars = [] ][, array<string|int, mixed> $options = [] ][, bool $raw = false ][, null|SchemaResolver|Closure|string $schema = null ][, array<string|int, mixed> $context = [] ]) : array<string|int, mixed>
    Parameters
    $query : string

    The AQL query string to execute

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

    Optional bind variables for the query

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

    Optional execution options

    $raw : bool = false

    If true, returns the object raw (no schema or alter applied)

    $schema : null|SchemaResolver|Closure|string = null

    The optional class name to map the document.

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

    Optional opaque context forwarded to AlterDocumentTrait::alter() and thus to the Alter::MAP callbacks (e.g. the originating $init, a skin, a locale…). Default [].

    Tags
    throws
    ArangoException
    ContainerExceptionInterface
    DependencyException
    NotFoundException
    NotFoundExceptionInterface
    ReflectionException
    Return values
    array<string|int, mixed>

    getExtra()

    Returns the AQL current extra datas.

    public getExtra() : array<string|int, mixed>
    Return values
    array<string|int, mixed>

    getFirstResult()

    Prepare, execute and returns the first result of the passed-in AQL query.

    public getFirstResult(string $query[, array<string|int, mixed> $bindVars = [] ][, array<string|int, mixed> $options = [] ][, bool $raw = false ][, null|SchemaResolver|Closure|string $schema = null ][, array<string|int, mixed> $context = [] ]) : mixed
    Parameters
    $query : string

    The AQL query string to execute

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

    Optional bind variables for the query

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

    Optional execution options

    $raw : bool = false

    If true, returns the object raw (no schema or alter applied)

    $schema : null|SchemaResolver|Closure|string = null

    The optional class name to map the document.

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

    Optional opaque context forwarded to AlterDocumentTrait::alter() and thus to the Alter::MAP callbacks (e.g. the originating $init, a skin, a locale…). Default [].

    Tags
    throws
    ArangoException
    ContainerExceptionInterface
    DependencyException
    NotFoundException
    NotFoundExceptionInterface
    ReflectionException

    getObject()

    Prepare, execute and returns an object with the passed-in AQL query.

    public getObject(string $query[, array<string|int, mixed> $bindVars = [] ][, array<string|int, mixed> $options = [] ][, bool $raw = false ][, null|SchemaResolver|Closure|string $schema = null ][, array<string|int, mixed> $context = [] ]) : object|null
    Parameters
    $query : string

    The AQL query string to execute

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

    Optional bind variables for the query

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

    Optional execution options

    $raw : bool = false

    If true, returns the object raw (no schema or alter applied)

    $schema : null|SchemaResolver|Closure|string = null

    The optional class name to map the document.

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

    Optional opaque context forwarded to AlterDocumentTrait::alter() and thus to the Alter::MAP callbacks (e.g. the originating $init, a skin, a locale…). Default [].

    Tags
    throws
    ArangoException
    ContainerExceptionInterface
    NotFoundExceptionInterface
    ReflectionException
    DependencyException
    NotFoundException
    Return values
    object|null

    getProfile()

    Returns the typed profile of the last profiled query run (per-phase timings, {@see ExecutionStats}, warnings).

    public getProfile() : ProfileResult
    Return values
    ProfileResult

    getResult()

    Prepare, execute and returns an array with the passed-in AQL query.

    public getResult(string $query[, array<string|int, mixed> $bindVars = [] ][, array<string|int, mixed> $options = [] ][, bool $raw = false ][, null|SchemaResolver|Closure|string $schema = null ][, array<string|int, mixed> $context = [] ]) : array<string|int, mixed>|null
    Parameters
    $query : string

    The AQL query string to execute

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

    Optional bind variables for the query

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

    Optional execution options

    $raw : bool = false

    If true, returns the object raw (no schema or alter applied)

    $schema : null|SchemaResolver|Closure|string = null

    The optional class name to map the document.

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

    Optional opaque context forwarded to AlterDocumentTrait::alter() and thus to the Alter::MAP callbacks (e.g. the originating $init, a skin, a locale…). Default [].

    Tags
    throws
    ArangoException
    ContainerExceptionInterface
    DependencyException
    NotFoundException
    NotFoundExceptionInterface
    ReflectionException
    Return values
    array<string|int, mixed>|null

    getStats()

    Returns the typed execution statistics of the last query (scanned / filtered / time / memory …). Most meaningful right after a profiled `list()` / `get()` (see {@see Arango::PROFILE}).

    public getStats() : ExecutionStats
    Return values
    ExecutionStats

    initializeCollection()

    Sets the internal collection reference.

    public initializeCollection([array<string|int, mixed> $init = [] ][, int $type = CollectionType::DOCUMENT ]) : static
    Parameters
    $init : array<string|int, mixed> = []

    The options to lazy creates the collection (document or edge) or not.

    • collection (string) Indicates if the name of the collection.
    • indexes (array) The optional list of indexes to creates (if not exist and lazy).
    • lazy (bool) Indicates if the collection is created if not exist — resolved through LazyTrait::isLazy(), so a lazy entry defined in the DI container always wins (orchestration kill-switch), then this init key, then the property default.
    • options (array) The options are:
      • 'waitForSync' : if set to true, then all removal operations will instantly be synchronised to disk / If this is not specified, then the collection's default sync behavior will be applied.
      • 'isSystem' : false->user collection(default), true->system collection .
      • 'keyOptions' : key options to use.
      • 'distributeShardsLike' : name of prototype collection for identical sharding.
      • 'numberOfShards' : number of shards for the collection.
      • 'replicationFactor' : number of replicas to keep (default: 1).
      • 'writeConcern' : minimum number of replicas to be successful when writing (default: 1).
      • 'shardKeys' : array of shard key attributes.
      • 'shardingStrategy' : sharding strategy to use in cluster.
      • 'smartJoinAttribute' : attribute name for smart joins (if not shard key).
      • 'schema' : collection schema.
    $type : int = CollectionType::DOCUMENT

    The default type of the collection (Default -> 'document' [2] )

    Tags
    throws
    ContainerExceptionInterface

    If an error occurs while reading the container lazy entry.

    NotFoundExceptionInterface

    If the container lazy entry vanishes between check and read.

    ReflectionException
    Return values
    static

    initializeDatabase()

    Set the internal arangoDB reference.

    public initializeDatabase([array<string|int, mixed> $init = [] ][, ContainerInterface|null $container = null ]) : static
    Parameters
    $init : array<string|int, mixed> = []
    $container : ContainerInterface|null = null
    Tags
    throws
    ContainerExceptionInterface
    NotFoundExceptionInterface
    Return values
    static

    initializeEdges()

    Initialize the 'edges' definitions.

    public initializeEdges([array<string|int, mixed> $init = [] ]) : static
    Parameters
    $init : array<string|int, mixed> = []
    Return values
    static

    initializeFields()

    Initialize fields definitions from an associative array.

    public initializeFields([array<string, mixed> $init = [] ]) : static
    Parameters
    $init : array<string, mixed> = []

    Optional initialization array containing a 'fields' key.

    Return values
    static

    initializeIndexes()

    Sets the declared indexes of the collection from the init definition, normalizing a single {@see IndexOptions} value to a one-element list (a raw array always stays the index list) — so every consumer sees a plain `IndexOptions[]`: the {@see initializeCollection()} lazy provisioning and the {@see DoctorTrait} diagnose/repair diffs.

    public initializeIndexes([array<string|int, mixed> $init = [] ]) : static
    Parameters
    $init : array<string|int, mixed> = []

    The init definition (reads the Arango::INDEXES key).

    Return values
    static

    initializeJoins()

    Initialize the 'joins' definitions.

    public initializeJoins([array<string|int, mixed> $init = [] ]) : static
    Parameters
    $init : array<string|int, mixed> = []
    Return values
    static

    initializeSkinFields()

    Initialize the per-skin projections registry from an associative array.

    public initializeSkinFields([array<string, mixed> $init = [] ]) : static
    Parameters
    $init : array<string, mixed> = []

    Optional initialization array containing an AQL::SKIN_FIELDS key.

    Return values
    static

    prepareAndExecute()

    Prepare and execute an ArangoDB AQL query.

    public prepareAndExecute(string $query[, array<string|int, mixed> $bindVars = [] ][, array<string|int, mixed> $options = [] ][, array<string|int, mixed>|null $optionalBinds = null ]) : static

    A bind variable may be optional : supplied by the caller (through Arango::BINDS) yet not guaranteed to appear in the final query text. This happens with a conditional projection — e.g. an aqlBindRef() inside a Field::WHERE / Field::WHEN carried by a field that the active skin (or an explicit ?fields) does not project. ArangoDB rejects a query that declares a bind it never references ("bind parameter 'x' was not declared in the query"), so such a leftover bind must be dropped before execution.

    $optionalBinds names the binds that are allowed to be absent :

    • it is opt-in and bounded — a bind whose name is not listed is never touched, so a query that uses no conditional bind behaves exactly as before ;
    • a listed bind is kept only when the query actually references it (@name, word-boundary matched to avoid a prefix collision such as @offers matching inside @offersScope) ;
    • passing [] disables the pruning explicitly.

    When $optionalBinds is null (the default), the list is derived from the model's own declarations — every AqlBindReference found anywhere in $this->fields / $this->skinFields and in the relation registries $this->edges / $this->joins (see collectOptionalBindNames()). The registries matter as much as the projections: a relation definition is a declaration tree of its own, it can carry a conditional bind (in its own AQL::FIELDS sub-projection, or in a definition-level predicate), and a skin dropping the relation leaves that bind unreferenced exactly the same way. The source of truth is the same aqlBindRef() that declared the conditional bind, so no host wiring is required, and over-listing a bind that turns out to be always present is inert (a referenced bind is always kept). Because this runs at the single execution chokepoint, it protects every query method (get(), list(), count(), exist(), edges…) uniformly.

    Parameters
    $query : string

    The AQL query string to execute.

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

    Optional bind variables for the query.

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

    Optional execution options.

    $optionalBinds : array<string|int, mixed>|null = null

    Names of binds allowed to be absent from the query. null derives the list from the model field definitions and relation registries ; [] disables the pruning.

    Tags
    throws
    ArangoException
    Return values
    static

    prepareQueryFields()

    Prepares query fields based on internal definitions and optional skin filter.

    public prepareQueryFields([array<string|int, mixed>|null $fields = null ][, string|null $skin = null ][, string|null $parentKey = null ][, string|array<string|int, mixed>|null $in = null ]) : array<string, array<string|int, mixed>>|null

    Converts string filters to array format, applies skins, and normalizes each field. When $fields is null and the model declares a $skinFields registry, the projection is resolved per skin first ([$skin]['*']$fields — the same order as an edge/join AQL::SKIN_FIELDS). The skin filter applies at every nesting level : the sub-fields of a WRAP, DOCUMENT or MAP definition are prepared with the same skin, so a nested Field::SKINS marker is honored in depth. A structural field whose declared sub-fields are all removed by the skin — or whose own AQL::SKIN_FIELDS table resolves to nothing for the requested skin — is dropped from the result.

    Parameters
    $fields : array<string|int, mixed>|null = null

    Optional custom fields to process (defaults to $this->fields).

    $skin : string|null = null

    Optional skin to filter applicable fields.

    $parentKey : string|null = null

    Optional parent key definition.

    $in : string|array<string|int, mixed>|null = null

    Optional field or list of fields to filter the final fields definitions.

    Tags
    example
    $fields = $model->prepareQueryFields('full');
    // Returns normalized array of fields including only those matching the 'full' skin
    
    Return values
    array<string, array<string|int, mixed>>|null

    Normalized fields ready for query, or null if none.

    registerProperty()

    Register a specific dynamic property in the binds and values collection to generates a query.

    public registerProperty(string $name, mixed $value, array<string|int, mixed> &$binds, array<string|int, mixed> &$values[, string $prefix = Char::EMPTY ][, string $separator = ': ' ]) : void
    Parameters
    $name : string
    $value : mixed
    $binds : array<string|int, mixed>
    $values : array<string|int, mixed>
    $prefix : string = Char::EMPTY
    $separator : string = ': '

    releaseEdges()

    Releases the 'edges' definitions.

    public releaseEdges() : static
    Return values
    static

    releasesJoins()

    Releases the 'joins' definitions.

    public releasesJoins() : static
    Return values
    static

    returnFields()

    Generates an AQL document expression or LET statement with the selected fields.

    public returnFields([array<string, mixed> $init = [] ][, array<string|int, mixed> &$variables = [] ][, bool $isVariable = false ]) : string

    Supports edges, joins, skins, and query fields.

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

    Options to customize the query:

    • string|array $fields: comma-separated list or array of field names
    • ?array $queryFields: prepared query fields (overrides internal $fields)
    • ?string $lang: optional language key
    • string $docRef: document reference name
    • bool $isResult: whether to assign to result variable
    $variables : array<string|int, mixed> = []
    $isVariable : bool = false

    Whether to generate a LET statement instead of RETURN

    Tags
    throws
    ContainerExceptionInterface
    NotFoundExceptionInterface
    Exception
    example
    $aql = $model->returnFields
    ([
        Arango::QUERY_FIELDS => $queryFields,
        Arango::DOC_REF      => 'doc',
        Arango::SKIN         => 'full'
    ]);
    
    Return values
    string

    Compiled AQL query fragment

    streamDocuments()

    Prepare, execute and returns a generator of documents with the passed-in AQL query.

    public streamDocuments(string $query[, array<string|int, mixed> $bindVars = [] ][, array<string|int, mixed> $options = [] ][, bool $raw = false ][, null|SchemaResolver|Closure|string $schema = null ][, array<string|int, mixed> $context = [] ]) : Generator<string|int, mixed>

    Documents are yielded one by one, allowing efficient memory usage for large result sets.

    Parameters
    $query : string

    The AQL query string to execute

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

    Optional bind variables for the query

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

    Optional execution options

    $raw : bool = false

    If true, returns the object raw (no schema or alter applied)

    $schema : null|SchemaResolver|Closure|string = null

    The optional class name to map the document.

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

    Optional opaque context forwarded to AlterDocumentTrait::alter() and thus to the Alter::MAP callbacks (e.g. the originating $init, a skin, a locale…). Default [].

    Tags
    throws
    ArangoException
    ContainerExceptionInterface
    DependencyException
    NotFoundException
    NotFoundExceptionInterface
    ReflectionException
    Return values
    Generator<string|int, mixed>

    Generator yielding documents one by one

    viewCreate()

    Creates an `arangosearch` View if it does not already exist.

    public viewCreate(string $name[, array<string|int, mixed> $links = [] ][, array<string|int, mixed> $options = [] ]) : bool
    Parameters
    $name : string

    The name of the new View.

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

    Per-collection link map (collection name → link definition).

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

    Extra arangosearch options forwarded verbatim.

    Return values
    bool

    Returns true if the new View has been created.

    viewExists()

    Checks if a View exists.

    public viewExists(string $name) : bool
    Parameters
    $name : string

    The name of the View.

    Return values
    bool

    firstRowAsArray()

    Runs a single-row aggregate query and normalizes its result to an array.

    protected firstRowAsArray(string $query[, array<string|int, mixed> $bindVars = [] ]) : array<string|int, mixed>

    The aggregate queries — DocumentsBoundsTrait::bounds(), DocumentsFacetCountsTrait::facetCounts() — all return one row holding one entry per requested dimension, and all face the same two shapes: their builder yields an empty string when nothing is computable, and the row itself comes back as an object or as an array depending on how the driver decoded it. Both are handled here rather than at each call site.

    The result is read raw — no schema, no alter() — because the row is a map of computed values, not a document.

    Parameters
    $query : string

    The compiled aggregate query, or an empty string when there is nothing to compute.

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

    The bind variables of that query.

    Tags
    throws
    ArangoException
    ContainerExceptionInterface
    DependencyException
    NotFoundException
    NotFoundExceptionInterface
    ReflectionException
    Return values
    array<string|int, mixed>

    The single row as an associative array; an empty array when the query is empty or the row is neither an object nor an array.

    profileOptions()

    Merges the cursor `profile` option into `$options` when the `$init` array requests profiling via {@see Arango::PROFILE} (`true` → profile level 2, or an explicit integer level). Returns `$options` unchanged otherwise.

    protected profileOptions(array<string|int, mixed> $init[, array<string|int, mixed> $options = [] ]) : array<string|int, mixed>
    Parameters
    $init : array<string|int, mixed>

    The model input array (list() / get()).

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

    The cursor options to augment.

    Return values
    array<string|int, mixed>

    collectOptionalBindNames()

    Collects every {@see AqlBindReference} name declared anywhere in one or more declaration trees — the projections (`$fields` / `$skinFields`) **and** the relation registries (`$edges` / `$joins`), typically inside a `Field::WHERE` / `Field::WHEN` condition. These are the *optional* binds : a skin (or an explicit `?fields`) can drop the carrying field — or the whole relation — from the projection, so the declared bind may not reach the final query text.

    private collectOptionalBindNames(array<string|int, mixed> ...$trees) : array<int, string>

    The walk is recursive and depth-agnostic : it descends into Field::FIELDS, edges and joins sub-definitions, and picks up a bind reference wherever it sits. Non-array leaves are visited but ignored, so a registry holding a resolved model instance or a callable is harmless. Collecting the raw (un-skinned) definitions is intentional — the superset of all possibly-optional binds is exactly what the execution layer must be allowed to prune.

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

    One or more declaration arrays to scan.

    Return values
    array<int, string>

    The de-duplicated list of bind names.

    filterFieldsBySkin()

    Filters fields based on an optional skin.

    private filterFieldsBySkin(array<string, mixed> $fields, string|null $skin) : array<string, mixed>
    Parameters
    $fields : array<string, mixed>

    Fields to filter

    $skin : string|null

    Skin to match

    Return values
    array<string, mixed>

    Filtered fields

    generateUniqueKey()

    Generates a unique key for special filters like edges, joins, or unique names.

    private generateUniqueKey(string $key, string|null $filter[, string|null $parentKey = null ]) : string|null
    Parameters
    $key : string

    Base field key

    $filter : string|null

    Filter type

    $parentKey : string|null = null

    Optional parent key.

    Return values
    string|null

    Generated unique key or existing

    normalizeFieldDefinition()

    Normalize a field definition into a structured array for queries.

    private normalizeFieldDefinition(string $key[, array<string|int, mixed> $options = [] ][, string|null $parentKey = null ][, string|null $skin = null ]) : array<string, mixed>|null
    • Converts string filters to array
    • Handles subfields for DOCUMENT or MAP filters
    • Generates unique keys for special filters

    The sub-fields of a structural filter (WRAP, DOCUMENT, MAP) are prepared recursively with the SAME skin, so a Field::SKINS marker on a nested sub-field is honored at every depth — with the level-one rules: a sub-field without a marker is always kept, and a null skin keeps everything. When the skin filters out ALL the declared sub-fields, the method returns null and the field itself is dropped from the projection (key absent).

    A structural field can also declare per-skin alternative sub-projections through AQL::SKIN_FIELDS (same table shape and resolution order as an edge/join definition). A declared table that resolves to nothing for the requested skin drops the field the same way (returns null).

    Parameters
    $key : string

    Field name

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

    Field options, may include:

    • Field::FILTER
    • Field::NAME
    • Field::QUOTED
    • Field::FIELDS (for DOCUMENT or MAP)
    $parentKey : string|null = null

    The Optional parent key

    $skin : string|null = null

    Optional skin propagated to the nested sub-fields.

    Tags
    example
    $normalized = $this->normalizeFieldDefinition( 'permissions',
    [
        Field::FILTER => Filter::EDGES,
        Field::SKINS => [Skin::FULL]
    ]);
    
    Return values
    array<string, mixed>|null

    Normalized field definition, or null when the skin removed every declared sub-field.

    On this page

    Search results