Oihana PHP Arango

DocumentFieldSetResolver implements Invalidable

Resolves — and caches — the set of values taken by one field across the documents of a collection matching a filter.

Typical use: a small, slow-moving reference set that a hot query needs on every call (the switched-off terms of a thesaurus, the keys of the disabled tenants, …). Asking the collection per request would cost one extra query on every listing, so the set is resolved once and cached.

The NATIVE type of each value is preserved, never normalised: a consuming document stores the reference with the type its own mapping produced, and AQL does not coerce across types — 5 NOT IN ["5"] is true, so a normalised set would filter nothing at all, silently.

Cache lifecycle:

  • Lazy: built on the first values() call after a cold cache.
  • Shared: Memcached is shared by every worker, so one invalidation reaches the whole fleet.
  • TTL safety net: bounds staleness if an invalidation point is ever missed.
  • Surgical invalidation: invalidate() is wired on the source model's write signals (see Arango::INVALIDATES), so a write takes effect at once.

Fail-open by design: a read failure yields an empty set. A cache miss or an unreachable collection must never be mistaken for "everything is excluded".

Tags
author

Marc Alcaraz

since
1.6.0

Table of Contents

Interfaces

Invalidable

Constants

DEFAULT_FIELD  : string = 'id'
The field collected when none is given — the foreign reference a consuming document usually stores, rather than the ArangoDB `_key`.
DEFAULT_TTL  : int = 3600
Default cache TTL in seconds (1 hour) — a safety net, not the primary refresh path (the write signals are).

Properties

$cache  : Memcached
$cacheKey  : string
$field  : string
$filter  : array<string|int, mixed>|null
$logger  : LoggerInterface|null
$model  : Documents
$ttl  : int

Methods

__construct()  : mixed
Creates a new DocumentFieldSetResolver.
invalidate()  : void
Drops the cached set.
values()  : array<int, int|string>
Returns the set of values, de-duplicated and re-indexed.
collect()  : array<int, int|string>
Reads the documents matching the given filter and collects their field values.
listInit()  : array<string, mixed>
Builds the model init of one read.
load()  : array<int, int|string>
Resolves the set, failing open on a read error.

Constants

DEFAULT_FIELD

The field collected when none is given — the foreign reference a consuming document usually stores, rather than the ArangoDB `_key`.

public string DEFAULT_FIELD = 'id'

DEFAULT_TTL

Default cache TTL in seconds (1 hour) — a safety net, not the primary refresh path (the write signals are).

public int DEFAULT_TTL = 3600

Properties

Methods

__construct()

Creates a new DocumentFieldSetResolver.

public __construct(Documents $model, Memcached $cache, string $cacheKey[, array<string|int, mixed>|null $filter = null ][, string $field = self::DEFAULT_FIELD ][, int $ttl = self::DEFAULT_TTL ][, LoggerInterface|null $logger = null ]) : mixed
Parameters
$model : Documents

The collection to read.

$cache : Memcached

The shared Memcached connection.

$cacheKey : string

Cache key — REQUIRED and unique per resolver: two resolvers behind one key would serve each other's set.

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

The filter selecting the documents, in the model filter shape. null reads them all.

$field : string = self::DEFAULT_FIELD

The field whose values are collected.

$ttl : int = self::DEFAULT_TTL

Cache TTL in seconds. 0 disables the cache (debugging only).

$logger : LoggerInterface|null = null

Optional logger.

values()

Returns the set of values, de-duplicated and re-indexed.

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

An empty array means "nothing matched": the caller should then pose no predicate at all rather than an always-true NOT IN [].

Return values
array<int, int|string>

collect()

Reads the documents matching the given filter and collects their field values.

protected collect(array<string|int, mixed>|null $filter) : array<int, int|string>

Mechanics only — read, extract, de-duplicate. The fail-open policy lives in load(): a subclass reading twice must be able to tell WHICH read failed, which a catch buried here would hide.

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

The filter selecting the documents, in the model filter shape. null reads them all.

Tags
throws
Throwable

Whatever the underlying read throws.

Return values
array<int, int|string>

listInit()

Builds the model init of one read.

protected listInit(array<string|int, mixed>|null $filter) : array<string, mixed>

The seam a subclass overrides to narrow the read — the whole document is fetched here, since the filtered set is small by construction.

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

The filter selecting the documents. null reads them all.

Return values
array<string, mixed>

load()

Resolves the set, failing open on a read error.

protected load() : array<int, int|string>
Return values
array<int, int|string>
On this page

Search results