Oihana PHP Arango

HasFilterArray

This trait defines the array filter helpers.

Config

Defines the 'filters' property in the model (Documents) definition.

Models::PLACES => fn( ContainerInterface $container ) => new Documents
(
    $container ,
    Collections::PLACES ,
    [
        ...
        AQL::FILTERS =>
        [
             Prop::EVENTS => FilterType::ARRAY ,
             ...
        ]
        ...
Tags
example
?filter={ "key":"events" , "at"=>"0" , "op":"eq" , "val":100 }
?filter={ "key":"events" , "op":"ge" , "alt"=>"count" , "val":100  }

Comparators

ALL operator

?filter={ "key":"values" , "op":"all.eq" , "val":4 } -> FILTER doc.values ALL == 4
?filter={ "key":"values" , "op":"all.ne" , "val":4 } -> FILTER doc.values ALL != 4
?filter={ "key":"values" , "op":"all.gt" , "val":4 } -> FILTER doc.values ALL >  4
?filter={ "key":"values" , "op":"all.ge" , "val":4 } -> FILTER doc.values ALL >= 4
?filter={ "key":"values" , "op":"all.lt" , "val":4 } -> FILTER doc.values ALL <  4
?filter={ "key":"values" , "op":"all.le" , "val":4 } -> FILTER doc.values ALL <= 4
?filter={ "key":"values" , "op":"all.in" , "val":[2,3,4] } -> FILTER doc.values ALL IN [2,3,4]
?filter={ "key":"values" , "op":"all.nin" , "val":[2,3,4] } -> FILTER doc.values ALL NOT IN [2,3,4]

ANY operator

?filter={ "key":"values" , "op":"any.eq" , "val":4 } -> FILTER doc.values ANY == 4
?filter={ "key":"values" , "op":"any.ne" , "val":4 } -> FILTER doc.values ANY != 4
?filter={ "key":"values" , "op":"any.gt" , "val":4 } -> FILTER doc.values ANY >  4
?filter={ "key":"values" , "op":"any.ge" , "val":4 } -> FILTER doc.values ANY >= 4
?filter={ "key":"values" , "op":"any.lt" , "val":4 } -> FILTER doc.values ANY <  4
?filter={ "key":"values" , "op":"any.le" , "val":4 } -> FILTER doc.values ANY <= 4
?filter={ "key":"values" , "op":"any.in" , "val":[2,3,4] } -> FILTER doc.values ANY IN [2,3,4]
?filter={ "key":"values" , "op":"any.nin" , "val":[2,3,4] } -> FILTER doc.values ANY NOT IN [2,3,4]

NONE operator

?filter={ "key":"values" , "op":"none.eq" , "val":4 } -> FILTER doc.values NONE == 4
?filter={ "key":"values" , "op":"none.ne" , "val":4 } -> FILTER doc.values NONE != 4
?filter={ "key":"values" , "op":"none.gt" , "val":4 } -> FILTER doc.values NONE >  4
?filter={ "key":"values" , "op":"none.ge" , "val":4 } -> FILTER doc.values NONE >= 4
?filter={ "key":"values" , "op":"none.lt" , "val":4 } -> FILTER doc.values NONE <  4
?filter={ "key":"values" , "op":"none.le" , "val":4 } -> FILTER doc.values NONE <= 4
?filter={ "key":"values" , "op":"none.in" , "val":[2,3,4] } -> FILTER doc.values NONE IN [2,3,4]
?filter={ "key":"values" , "op":"none.nin" , "val":[2,3,4] } -> FILTER doc.values NONE NOT IN [2,3,4]

Functions

?filter={ "key":"values" , "op":"ge" , "val":10 , "alt":"avg"    } -> FILTER AVERAGE(doc.values) >= 10
?filter={ "key":"values" , "op":"ge" , "val":10 , "alt":"count"  } -> FILTER LENGTH(doc.values) >= 10
?filter={ "key":"values" , "op":"ge" , "val":10 , "alt":"first"  } -> FILTER FIRST(doc.values) >= 10
?filter={ "key":"values" , "op":"ge" , "val":10 , "alt":"last"   } -> FILTER LAST(doc.values) >= 10
?filter={ "key":"values" , "op":"ge" , "val":10 , "alt":"max"    } -> FILTER MAX(doc.values) >= 10
?filter={ "key":"values" , "op":"ge" , "val":10 , "alt":"median" } -> FILTER MEDIAN(doc.values) >= 10
?filter={ "key":"values" , "op":"ge" , "val":10 , "alt":"min"    } -> FILTER MIN(doc.values) >= 10
?filter={ "key":"values" , "op":"ge" , "val":10 , "alt":"sum"    } -> FILTER SUM(doc.values) >= 10
?filter={ "key":"values" , "op":"ge" , "val":10 , "alt":"nth" , "pos":2 } -> FILTER NTH(doc.values,2) >= 10
?filter={ "key":"values" , "op":"ge" , "val":10 , "alt":"percentile" , "pos":20 , "method":"interpolation" } -> FILTER PERCENTILE(doc.values,20,"interpolation") >= 10
?filter={ "key":"values" , "op":"ge" , "val":10 , "alt":"product" } -> FILTER PRODUCT(doc.values) >= 10

Table of Contents

Methods

buildMatchCondition()  : string
Builds a `match` condition over an array of objects — a multi-field test on the ELEMENTS, not a question about how many there are.
prepareFilterArray()  : string
Prepares the filter clause with a string attribute.
prepareFilterArrayComparator()  : string
Prepares the filter clause with a specific operator.
prepareFilterArrayKey()  : string
Prepares the filter clause of a string attribute with a specific key and document.
prepareFilterAtLeast()  : string
Builds an `AT LEAST (n)` array quantifier filter: at least `n` elements of the array satisfy the comparison.
prepareFilterQuantified()  : string
Builds a quantified comparison on a scalar array via the `quant` key: how many elements satisfy the comparison.
quantifiedArrayCondition()  : string
Builds a quantified condition over a scalar array, in the one shape that counts correctly: `array[? <quantifier> FILTER CURRENT <cmp> @value]`.

Methods

buildMatchCondition()

Builds a `match` condition over an array of objects — a multi-field test on the ELEMENTS, not a question about how many there are.

protected buildMatchCondition(array<string|int, mixed> $match, array<string|int, mixed>|null &$binds, string $baseKey, array<string|int, mixed> $allowedFields, mixed $alt, mixed $quant) : string

🔑 Shared by both depths on purpose. The flat lookup reaches it for a key written at the root (attachments[*]), the hierarchical walk for one written behind an object (resolution.steps[*]). They used to build it separately, and only one of them built it at all: the walk answered a bare cardinality instead, silently replacing the caller's question with another one. One builder is the point of this method — the two callers now differ only in what they hand it.

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

The match payload (sub-field => value, …).

$binds : array<string|int, mixed>|null

The bind variables, populated by reference.

$baseKey : string

The fully qualified AQL key of the array (doc.attachments, doc.resolution.steps).

$allowedFields : array<string|int, mixed>

The declared sub-fields. Empty means no validation, so a caller that cannot resolve them must say so rather than pass [].

$alt : mixed

The resolved alt chain, applied inside the inline condition.

$quant : mixed

The element-axis quantifier, or null for the existential form.

Tags
throws
BindException
UnsupportedOperationException
ValidationException
Return values
string

prepareFilterArray()

Prepares the filter clause with a string attribute.

protected prepareFilterArray([array<string|int, mixed> $init = [] ][, array<string|int, mixed>|null &$binds = null ][, string $docRef = AQL::DOC ]) : string
Parameters
$init : array<string|int, mixed> = []
$binds : array<string|int, mixed>|null = null
$docRef : string = AQL::DOC
Tags
throws
BindException
UnsupportedOperationException
ValidationException
Return values
string

prepareFilterArrayComparator()

Prepares the filter clause with a specific operator.

protected prepareFilterArrayComparator([array<string|int, mixed> $init = [] ]) : string
Parameters
$init : array<string|int, mixed> = []
Return values
string

prepareFilterArrayKey()

Prepares the filter clause of a string attribute with a specific key and document.

protected prepareFilterArrayKey([string|array<string|int, mixed>|null $init = [] ][, string $docRef = AQL::DOC ][, array<string|int, mixed>|null &$binds = null ]) : string
Parameters
$init : string|array<string|int, mixed>|null = []
$docRef : string = AQL::DOC
$binds : array<string|int, mixed>|null = null
Tags
throws
UnsupportedOperationException
ValidationException
Return values
string

prepareFilterAtLeast()

Builds an `AT LEAST (n)` array quantifier filter: at least `n` elements of the array satisfy the comparison.

protected prepareFilterAtLeast(array<string|int, mixed> $init[, array<string|int, mixed>|null &$binds = null ][, string $docRef = AQL::DOC ]) : string

The operator is the array form ["atLeast.<cmp>", n] (element 0 is the atLeast.<cmp> code, element 1 the threshold, defaulting to 1). The <cmp> suffix reuses FilterComparator (eq, ne, gt, ge, lt, le, in, nin). The threshold is cast to an int and inlined (injection-safe); the value is bound. The compared key stays alt-aware.

doc.scores AT LEAST (2) >= @value
Parameters
$init : array<string|int, mixed>

The filter init (op = ["atLeast.<cmp>", n]).

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

The bind variables, populated by reference.

$docRef : string = AQL::DOC

The document reference.

Tags
throws
BindException
UnsupportedOperationException
ValidationException
Return values
string

prepareFilterQuantified()

Builds a quantified comparison on a scalar array via the `quant` key: how many elements satisfy the comparison.

protected prepareFilterQuantified(array<string|int, mixed> $init[, array<string|int, mixed>|null &$binds = null ][, string $docRef = AQL::DOC ]) : string

The comparator stays in op (a plain FilterComparator code such as ge); the element-axis quantifier comes from quant and is resolved by resolveQuantifier into ANY / ALL / NONE / AT LEAST (n). This is the unified, recommended form; the legacy op:"all.ge" and op:["atLeast.ge", n] notations remain valid aliases.

doc.scores ALL >= @value
doc.scores AT LEAST (2) >= @value
Parameters
$init : array<string|int, mixed>

The filter init (op = comparator code, quant = quantifier).

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

The bind variables, populated by reference.

$docRef : string = AQL::DOC

The document reference.

Tags
throws
BindException
UnsupportedOperationException
ValidationException
Return values
string

quantifiedArrayCondition()

Builds a quantified condition over a scalar array, in the one shape that counts correctly: `array[? <quantifier> FILTER CURRENT <cmp> @value]`.

private quantifiedArrayCondition(array<string|int, mixed> $init, array<string|int, mixed>|null &$binds, string $docRef, string $quantifier, string $comparator) : string

🚨 Not the infix array comparison operator. doc.tags AT LEAST (3) == @v reads naturally and is wrong: ArangoDB answers true whenever the array holds fewer than n elements, whatever they are — [] AT LEAST (99) == "x" is true. So "records with at least three matching tags" answered "records with fewer than three tags", the opposite of the question, in 200.

The question-mark operator counts the elements that actually match, and it is what the object-array branch of this same filter has always used. ANY, ALL and NONE were correct in either spelling — measured, row for row — so all four go through here rather than leaving two shapes in one method depending on what quant happens to hold.

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

The filter init.

$binds : array<string|int, mixed>|null

The bind variables, populated by reference.

$docRef : string

The document reference.

$quantifier : string

The resolved AQL quantifier (ANY, ALL, NONE, AT LEAST (n)).

$comparator : string

The resolved AQL comparator applied to each element.

Tags
throws
BindException
UnsupportedOperationException
ValidationException
Return values
string
On this page

Search results