Oihana PHP Arango

BoundsQueryTrait uses trait:short

Builds the AQL query that computes the numeric **bounds** — the `{ min, max, count }` extent — of several fields at once, alongside (not replacing) the document list.

Each requested field is a key of the model's $this->bounds whitelist. The extent is aggregated over the same conjunctive filter as the list, so the bounds frame the currently filtered set (a ?bounds= request scoped by ?filter= / ?search / a facet narrows to that subset). Alongside the two scalars, count reports how many values framed the extent (post-exclusion, non-null) — so a client knows whether a range control is worth showing.

Flat scalar fields share a single COLLECT AGGREGATE — one pass over the filtered set frames every one of them at once:

FOR doc IN @@coll FILTER <same filters>
COLLECT AGGREGATE width_min = MIN(doc.width), width_max = MAX(doc.width), width_count = SUM(doc.width != null ? 1 : 0)
RETURN { width: { min: width_min, max: width_max, count: width_count } }

A nested measure declared with the [*] array-expansion marker (offers[*].price) cannot share that root FOR — it must unwind the array — so it gets its own LET sub-query, merged into the flat block.

Exclusions. A bound definition can drop values from the aggregate through Bound options (POSITIVE> 0, MIN / MAX → accepted domain, IGNORE → sentinel value(s)). An excluded value is mapped to null — which MIN / MAX already ignore — so the guard is per field: a document dropped from one field's extent still frames the others.

COLLECT AGGREGATE width_min = MIN(doc.width > 0 ? doc.width : null), … , width_count = SUM(doc.width > 0 ? 1 : 0)
Tags
see
BoundsQueryTrait::buildBoundsQuery()

The entry point.

since
1.0.0
author

Marc Alcaraz

Table of Contents

Constants

BOUND_CNT  : string = 'cnt'
The count aggregate variable of a nested sub-query.
BOUND_COUNT  : string = 'count'
The count attribute name in the returned `{ min, max, count }` object.
BOUND_HI  : string = 'hi'
The upper-bound aggregate variable of a nested sub-query.
BOUND_ITEM  : string = 'item'
The unwind loop variable for nested ([*]) bound fields.
BOUND_LO  : string = 'lo'
The lower-bound aggregate variable of a nested sub-query.
BOUND_MAX  : string = 'max'
The upper-bound attribute name in the returned `{ min, max, count }` object.
BOUND_MIN  : string = 'min'
The lower-bound attribute name in the returned `{ min, max, count }` object.
BOUND_NULL  : string = 'null'
The AQL `null` literal — the value an excluded measure maps to.
BOUNDS_FLAT  : string = '__bounds'
The `LET` variable holding the flat-fields extent object, merged with the nested-field sub-queries.

Methods

buildBoundsQuery()  : string
Builds the bounds query, or an empty string when nothing is boundable.
buildFilteredScope()  : array{0: string, 1: ?string}
Builds the `FOR` segment and the conjunctive `FILTER` clause shared by the list-family queries.
assembleBoundsQuery()  : string
Assembles the final query from the flat block and the nested `LET`s.
boundCondition()  : string|null
Builds the AQL boolean condition a value must satisfy to enter the extent, from the declaration's exclusion options, or null when none is declared.
boundCount()  : string
The count expression fed to `SUM`: `1` for each value that frames the extent (non-null, and passing the exclusion condition when declared), `0` otherwise — so `count` reports how many values the `{ min, max }` spans.
boundObject()  : string
Serializes a `{ min: <lo>, max: <hi>, count: <count> }` object from three AQL variables.
boundValue()  : string
The value expression fed to `MIN` / `MAX`: the raw reference when no exclusion is declared (`MIN` / `MAX` ignore `null` natively), or a `<condition> ? <reference> : null` guard that maps an excluded value to `null` so it does not skew the extent.
buildBoundsSubquery()  : string
Builds one nested ([*]) field's extent sub-query, unwinding each `[*]` hop with a `FOR` and aggregating `MIN` / `MAX` / count over the projected leaf.
normalizeBounds()  : array<string, array<string|int, mixed>>
Normalizes the `$bounds` whitelist to a `field => definition` map.

Constants

BOUND_CNT

The count aggregate variable of a nested sub-query.

private string BOUND_CNT = 'cnt'

BOUND_COUNT

The count attribute name in the returned `{ min, max, count }` object.

private string BOUND_COUNT = 'count'

BOUND_HI

The upper-bound aggregate variable of a nested sub-query.

private string BOUND_HI = 'hi'

BOUND_ITEM

The unwind loop variable for nested ([*]) bound fields.

private string BOUND_ITEM = 'item'

BOUND_LO

The lower-bound aggregate variable of a nested sub-query.

private string BOUND_LO = 'lo'

BOUND_MAX

The upper-bound attribute name in the returned `{ min, max, count }` object.

private string BOUND_MAX = 'max'

BOUND_MIN

The lower-bound attribute name in the returned `{ min, max, count }` object.

private string BOUND_MIN = 'min'

BOUND_NULL

The AQL `null` literal — the value an excluded measure maps to.

private string BOUND_NULL = 'null'

BOUNDS_FLAT

The `LET` variable holding the flat-fields extent object, merged with the nested-field sub-queries.

private string BOUNDS_FLAT = '__bounds'

Methods

buildBoundsQuery()

Builds the bounds query, or an empty string when nothing is boundable.

public buildBoundsQuery([array<string|int, mixed> $init = [] ][, array<string|int, mixed> &$bindVars = [] ][, string $docRef = AQL::DOC ]) : string
Parameters
$init : array<string|int, mixed> = []

The list query options (Arango::BOUNDS holds the fields).

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

The bind variables, populated by reference.

$docRef : string = AQL::DOC

The document reference.

Tags
throws
BindException
ConstantException
ContainerExceptionInterface
DependencyException
NotFoundException
NotFoundExceptionInterface
ReflectionException
UnsupportedOperationException
ValidationException
Return values
string

The compiled AQL query, or an empty string.

buildFilteredScope()

Builds the `FOR` segment and the conjunctive `FILTER` clause shared by the list-family queries.

protected buildFilteredScope([array<string|int, mixed> $init = [] ][, array<string|int, mixed> &$bindVars = [] ]) : array{0: string, 1: ?string}
Parameters
$init : array<string|int, mixed> = []

The query options.

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

The bind variables, populated by reference.

Tags
throws
BindException
ConstantException
ContainerExceptionInterface
DependencyException
NotFoundException
NotFoundExceptionInterface
ReflectionException
UnsupportedOperationException
ValidationException
Return values
array{0: string, 1: ?string}

The [ $for, $filter ] pair.

assembleBoundsQuery()

Assembles the final query from the flat block and the nested `LET`s.

private assembleBoundsQuery(string $for, string|null $filter, array<string|int, mixed> $aggregate, array<string|int, mixed> $flatReturn, array<string|int, mixed> $lets, array<string|int, mixed> $mergeParts) : string

Three shapes, cheapest first: a single flat block becomes the top-level query directly; nested-only fields return an object of their LETs; a mix binds the flat block to a LET and MERGEs the nested fields into it.

Parameters
$for : string

The shared FOR segment.

$filter : string|null

The shared FILTER clause.

$aggregate : array<string|int, mixed>

The flat COLLECT AGGREGATE assignments.

$flatReturn : array<string|int, mixed>

The flat RETURN entries.

$lets : array<string|int, mixed>

The nested-field LET clauses.

$mergeParts : array<string|int, mixed>

The nested-field RETURN entries.

Tags
throws
ReflectionException
UnsupportedOperationException
Return values
string

The compiled AQL query, or an empty string when nothing was boundable.

boundCondition()

Builds the AQL boolean condition a value must satisfy to enter the extent, from the declaration's exclusion options, or null when none is declared.

private boundCondition(string $reference, array<string|int, mixed> $definition) : string|null

Conditions combine with a logical AND: POSITIVE> 0, MIN / MAX → the accepted [ min, max ] domain, IGNORENOT IN [ … ] sentinels.

Parameters
$reference : string

The value reference (e.g. doc.width).

$definition : array<string|int, mixed>

The bound definition.

Tags
throws
UnsupportedOperationException
Return values
string|null

The AQL condition, or null when the value is unfiltered.

boundCount()

The count expression fed to `SUM`: `1` for each value that frames the extent (non-null, and passing the exclusion condition when declared), `0` otherwise — so `count` reports how many values the `{ min, max }` spans.

private boundCount(string $reference, array<string|int, mixed> $definition) : string
Parameters
$reference : string

The value reference.

$definition : array<string|int, mixed>

The bound definition.

Tags
throws
UnsupportedOperationException
Return values
string

The count expression.

boundObject()

Serializes a `{ min: <lo>, max: <hi>, count: <count> }` object from three AQL variables.

private boundObject(string $lo, string $hi, string $count) : string
Parameters
$lo : string

The lower-bound variable / expression.

$hi : string

The upper-bound variable / expression.

$count : string

The count variable / expression.

Tags
throws
UnsupportedOperationException
Return values
string

The { min: <lo>, max: <hi>, count: <count> } object literal.

boundValue()

The value expression fed to `MIN` / `MAX`: the raw reference when no exclusion is declared (`MIN` / `MAX` ignore `null` natively), or a `<condition> ? <reference> : null` guard that maps an excluded value to `null` so it does not skew the extent.

private boundValue(string $reference, array<string|int, mixed> $definition) : string
Parameters
$reference : string

The value reference.

$definition : array<string|int, mixed>

The bound definition.

Tags
throws
UnsupportedOperationException
Return values
string

The value expression.

buildBoundsSubquery()

Builds one nested ([*]) field's extent sub-query, unwinding each `[*]` hop with a `FOR` and aggregating `MIN` / `MAX` / count over the projected leaf.

private buildBoundsSubquery(string $property, array<string|int, mixed> $definition, string $for, string|null $filter, string $docRef) : string
Parameters
$property : string

The [*]-bearing property path.

$definition : array<string|int, mixed>

The bound definition (exclusion options).

$for : string

The pre-built root FOR segment.

$filter : string|null

The shared FILTER clause.

$docRef : string

The document reference.

Tags
throws
ReflectionException
UnsupportedOperationException
ValidationException
Return values
string

The FOR … COLLECT AGGREGATE … RETURN { min, max, count } sub-query.

normalizeBounds()

Normalizes the `$bounds` whitelist to a `field => definition` map.

private normalizeBounds() : array<string, array<string|int, mixed>>

Accepts both notations, mixed in the same declaration:

  • a bare field name (list entry, e.g. 'width') → an empty definition;
  • a keyed definition ('price' => [ Bound::PROPERTY => '…' ]) → itself (a non-array value, e.g. 'width' => true, becomes an empty definition).

The sole caller (buildBoundsQuery()) already guarantees $this->bounds is an array, so no defensive is_array guard is needed here.

Return values
array<string, array<string|int, mixed>>

The normalized whitelist (empty when nothing boundable).

On this page

Search results