VisibilityConstrainedDocumentSourceInterface
extends
DocumentSourceInterface
in
Source that can pass its visibility conditions to the ES query.
Optional extension of DocumentSourceInterface: a source without it sends the plain query (EsSearcher).
The DB stays the arbiter of visibility. Caller filters are still applied on both paths
(SearchTrait), so a stale document never leaks an
invisible entity; this interface only pre-narrows the ES side so paging runs over a reasonable
set. Adverts need it because expired and inactive ones stay in the index, so relevance paging
in ES would return short pages and an inflated totalCount.
IMPORTANT: the opposite direction (a document marked invisible but visible in the DB) is the price of pre-narrowing: such an entity drops out of search until a reindex or hook catches up. Therefore only conditions whose change the source can already propagate to the index belong here, plus query-time conditions over time, which cannot go stale.
Table of Contents
Methods
- buildDocuments() : array<string, array<string, array<string, mixed>>>
- Builds the documents of an entity as `indexBase => (_id => document)`. An empty array means the entity must not be indexed (deactivated or without an active translation), so it is deleted.
- expectedDocumentBounds() : array{min: int, max: int}
- Returns the expected range of the document count in the source index (across all bases and languages).
- fetchExistingIds() : array<string|int, int>
- Returns which of the given ids really exist in the DB; orphan cleanup deletes from ES the documents of entities no longer in the DB.
- fetchFresh() : array<int, object>
- Returns fresh entities after commit (service `find` with `useCache: false`). An entity from `completedSave` is not authoritative, because `afterSave` changes the DB through `updateColumn` after the flush. A missing id is omitted.
- fetchIdsChangedSince() : array<string|int, int>
- Returns ids of entities changed or created since `$since` (DB, no cache) as the input of the incremental sync. It must cover both insert and update (`insertTime` or `updateDatetime`); mutations outside the ORM (`updateColumn`, raw SQL) are never covered and the nightly full reindex catches them up.
- fetchReindexBatch() : array<int, object>
- Returns a batch of entities for a full reindex by key: `id > $afterId`, ordered ascending by id, at most `$limit` (with includes, no cache). The array key is the entity id; the last one becomes the cursor the next part of the reindex continues from.
- getAllDocumentIds() : array<string, array<string|int, string>>
- Returns every possible `_id` of the entity across languages as `indexBase => [_id, …]`.
- getEntityIdField() : string
- Returns the ES document field holding the entity id (e.g. `articleId`); sync sorts and pages (`search_after`) by it during the orphan scan.
- getIndexBaseForLanguage() : string|null
- Returns the index base for a language alias (`cs`), null when the language does not exist.
- getIndexBases() : array<string|int, string>
- Returns index base names without prefix and version; one per language for translated entities (e.g. `['blog_article_cs', 'blog_article_en']`).
- getIndexDefinition() : array<string, mixed>
- Returns the index definition (settings and mappings) for index creation.
- getKey() : string
- Returns the source key for the `enabledSources` allowlist and `EsSearcher`, e.g. `blog_article`.
- getSearchFields() : array<string, int|float>
- Returns the `multi_match` fields with boosts, e.g. `['name' => 3, 'perex' => 2, 'content' => 1]`.
- getVisibilityFilters() : array<int, array<string, mixed>>
- Returns clauses for `bool.filter` of the search query (they only narrow, the score is not affected).
Methods
buildDocuments()
Builds the documents of an entity as `indexBase => (_id => document)`. An empty array means the entity must not be indexed (deactivated or without an active translation), so it is deleted.
public
buildDocuments(object $entity) : array<string, array<string, array<string, mixed>>>
Parameters
- $entity : object
Return values
array<string, array<string, array<string, mixed>>>expectedDocumentBounds()
Returns the expected range of the document count in the source index (across all bases and languages).
public
expectedDocumentBounds() : array{min: int, max: int}
It must mirror the guards of buildDocuments() exactly, otherwise monitoring would report
a false drift. Used by EsMonitor to detect ES vs. DB mismatch. min === max for a single
language entity (one document per entity); for multi-language sources (Article) max is an
upper estimate, because not every entity has all languages active.
Return values
array{min: int, max: int}fetchExistingIds()
Returns which of the given ids really exist in the DB; orphan cleanup deletes from ES the documents of entities no longer in the DB.
public
fetchExistingIds(array<string|int, int> $ids) : array<string|int, int>
Parameters
- $ids : array<string|int, int>
Return values
array<string|int, int>fetchFresh()
Returns fresh entities after commit (service `find` with `useCache: false`). An entity from `completedSave` is not authoritative, because `afterSave` changes the DB through `updateColumn` after the flush. A missing id is omitted.
public
fetchFresh(array<string|int, int> $ids) : array<int, object>
Parameters
- $ids : array<string|int, int>
Return values
array<int, object> —keyed by id
fetchIdsChangedSince()
Returns ids of entities changed or created since `$since` (DB, no cache) as the input of the incremental sync. It must cover both insert and update (`insertTime` or `updateDatetime`); mutations outside the ORM (`updateColumn`, raw SQL) are never covered and the nightly full reindex catches them up.
public
fetchIdsChangedSince(DateTimeImmutable $since) : array<string|int, int>
Parameters
- $since : DateTimeImmutable
Return values
array<string|int, int>fetchReindexBatch()
Returns a batch of entities for a full reindex by key: `id > $afterId`, ordered ascending by id, at most `$limit` (with includes, no cache). The array key is the entity id; the last one becomes the cursor the next part of the reindex continues from.
public
fetchReindexBatch(int $afterId, int $limit) : array<int, object>
Parameters
- $afterId : int
- $limit : int
Return values
array<int, object> —keyed by id, ascending
getAllDocumentIds()
Returns every possible `_id` of the entity across languages as `indexBase => [_id, …]`.
public
getAllDocumentIds(int $id) : array<string, array<string|int, string>>
It serves targeted deletion of orphan language documents (orphanRemoval on translations)
and delete; delete_by_query must never be used.
Parameters
- $id : int
Return values
array<string, array<string|int, string>>getEntityIdField()
Returns the ES document field holding the entity id (e.g. `articleId`); sync sorts and pages (`search_after`) by it during the orphan scan.
public
getEntityIdField() : string
Return values
stringgetIndexBaseForLanguage()
Returns the index base for a language alias (`cs`), null when the language does not exist.
public
getIndexBaseForLanguage(string|null $languageAlias) : string|null
Parameters
- $languageAlias : string|null
Return values
string|nullgetIndexBases()
Returns index base names without prefix and version; one per language for translated entities (e.g. `['blog_article_cs', 'blog_article_en']`).
public
getIndexBases() : array<string|int, string>
Return values
array<string|int, string>getIndexDefinition()
Returns the index definition (settings and mappings) for index creation.
public
getIndexDefinition(string $indexBase) : array<string, mixed>
Parameters
- $indexBase : string
Return values
array<string, mixed>getKey()
Returns the source key for the `enabledSources` allowlist and `EsSearcher`, e.g. `blog_article`.
public
getKey() : string
Return values
stringgetSearchFields()
Returns the `multi_match` fields with boosts, e.g. `['name' => 3, 'perex' => 2, 'content' => 1]`.
public
getSearchFields() : array<string, int|float>
Return values
array<string, int|float>getVisibilityFilters()
Returns clauses for `bool.filter` of the search query (they only narrow, the score is not affected).
public
getVisibilityFilters() : array<int, array<string, mixed>>
They mirror what the DB considers visible. For adverts that is exactly two things, the same
pair the front end builds in AdvertListTrait::prepareFilters():
- a
termon the denormalized flag (generated DB columnactive), - a
rangeon the expiry date as a query-time condition (now/d), becauseNOW()cannot go into a generated column and would go stale in the index every midnight.
An empty array means no pre-narrowing is wanted (the query is then the plain one).