FacetCountsQueryTrait uses trait:short
Builds the AQL query that computes per-value **facet counts** for several dimensions at once, alongside (not replacing) the document list.
Each requested dimension is a key of the model's $this->facets whitelist
(the filterable facets become the counted facets). One LET sub-query per
dimension counts values over the same conjunctive filter as the list, so
the buckets reflect the currently filtered set:
LET category = (FOR doc IN @@coll FILTER <same filters> COLLECT value = doc.category WITH COUNT INTO count SORT count DESC RETURN { value, count })
LET status = (FOR doc IN @@coll FILTER <same filters> COLLECT value = doc.status WITH COUNT INTO count SORT count DESC RETURN { value, count })
RETURN { category, status }
v1 supports the scalar Facet::FIELD and the array-membership
Facet::IN family (Facet::LIST, Facet::LIST_FIELD,
Facet::LIST_FIELD_SORTED); other facet types are skipped. A
Facet::PROPERTY carrying the [*] array-expansion marker (e.g.
offers[*].priceCurrency) unwinds the object array and counts the sub-field
per element — see FacetCountsQueryTrait::buildFacetCountSubquery().
The unwinding facet types (the [*] expansion and the Facet::IN
family) count array elements by default, so a document whose array repeats
the same value in several elements is counted several times — diverging from
the equivalent ?filter= existence test, which counts documents. Declaring
Facet::DISTINCT => true on such a facet switches its bucket count to
COUNT_DISTINCT( doc._key ), so the count reflects distinct root documents
and matches the filter. The flag is opt-in (default unchanged) and a no-op on
the scalar Facet::FIELD type, which already counts one row per document.
Tags
Table of Contents
Constants
- FACET_COUNT_ITEM : string = 'item'
- The unwind loop variable for array-membership facets (kept distinct from {@see FacetCountsQueryTrait::FACET_COUNT_VALUE} to avoid a name collision).
- FACET_COUNT_VALUE : string = 'value'
- The bucket value attribute name in the returned rows (`{ value, count }`).
Methods
- buildFacetCountsQuery() : string
- Builds the multi-`LET` facet-counts query, or an empty string when nothing is countable.
- buildFilteredScope() : array{0: string, 1: ?string}
- Builds the `FOR` segment and the conjunctive `FILTER` clause shared by the list-family queries.
- buildFacetCountSubquery() : string|null
- Builds one dimension's counting sub-query, or null for an unsupported type.
- facetCountCollect() : array{0: string, 1: string, 2: string}
- The shared `COLLECT value = <expr> … SORT count DESC RETURN { value, count }` tail.
Constants
FACET_COUNT_ITEM
The unwind loop variable for array-membership facets (kept distinct from {@see FacetCountsQueryTrait::FACET_COUNT_VALUE} to avoid a name collision).
private
string
FACET_COUNT_ITEM
= 'item'
FACET_COUNT_VALUE
The bucket value attribute name in the returned rows (`{ value, count }`).
private
string
FACET_COUNT_VALUE
= 'value'
Methods
buildFacetCountsQuery()
Builds the multi-`LET` facet-counts query, or an empty string when nothing is countable.
public
buildFacetCountsQuery([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::FACET_COUNTSholds the dimensions). - $bindVars : array<string|int, mixed> = []
-
The bind variables, populated by reference.
- $docRef : string = AQL::DOC
-
The document reference.
Tags
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
Return values
array{0: string, 1: ?string} —The [ $for, $filter ] pair.
buildFacetCountSubquery()
Builds one dimension's counting sub-query, or null for an unsupported type.
private
buildFacetCountSubquery(array<string|int, mixed> $facet, string $key, string $for, string|null $filter, string $docRef) : string|null
Parameters
- $facet : array<string|int, mixed>
-
The facet definition (
Facet::TYPE,Facet::PROPERTY). - $key : string
-
The facet key (default property).
- $for : string
-
The pre-built
FORsegment shared by every dimension — the bound collection, or the bound View with itsSEARCHsegment when the View search is active. - $filter : string|null
-
The shared
FILTERclause. - $docRef : string
-
The document reference.
Tags
Return values
string|nullfacetCountCollect()
The shared `COLLECT value = <expr> … SORT count DESC RETURN { value, count }` tail.
private
facetCountCollect(string $expression, string $sort[, string|null $distinctKey = null ]) : array{0: string, 1: string, 2: string}
By default the bucket count is the number of unwound rows
(WITH COUNT INTO count). When $distinctKey is provided (opt-in
Facet::DISTINCT => true on an unwinding facet), the count becomes the
number of DISTINCT root documents in the bucket
(AGGREGATE count = COUNT_DISTINCT( <distinctKey> )), so a document whose
array repeats the same sub-field value is counted once — matching the
?filter= existence semantics. The aggregate is deliberately named
Group::COUNT_NAME (count) so the derived RETURN { value, count }
and the SORT count DESC clause stay identical in both modes.
Parameters
- $expression : string
-
The value expression to group on.
- $sort : string
-
The pre-built
SORT count DESCclause. - $distinctKey : string|null = null
-
The root document key expression to count distinctly (e.g.
doc._key), or null for the default per-element count.
Tags
Return values
array{0: string, 1: string, 2: string} —[ COLLECT, SORT, RETURN ] fragments.