ElasticReindexTrait
Best-effort ES reindex after admin mutations of an indexed entity.
The admin layer has no completedSave/completedDelete hooks
(SaveTrait is a thin delegation to the
service), and the watermark sync mostly does not see admin edits (nothing bumps the
entity update timestamp on the admin save path). Without this trait an admin change of
an indexed entity reaches ES only with a full reindex. Result visibility is not at risk
(SearchIdFilter is phase-one only, eligibility stays in the database); only freshness
of fulltext and facet counts suffers.
Usage: the admin manager injects EsEntityIndexer $esIndexer and its
DocumentSourceInterface implementation ($esDocumentSource) in the constructor and uses the trait. Deletion and
deactivation are handled by the indexer: when fetchFresh finds no row (or the
buildDocuments guard returns nothing), the documents are deleted. Fail-open: an ES
outage must not break a write that is already in the database.
IMPORTANT: updateColumn (singular) in the shared SaveTrait does not delegate to the
plural, so both are overridden here. A method of the class itself wins over the trait:
a class that overrides save() must call esReindexBestEffort() manually, otherwise
its saves are never reindexed.
Table of Contents
Methods
- delete() : Result
- save() : Result
- updateColumn() : Result
- updateColumns() : Result
- esReindexBestEffort() : void
- Catches ES up after an admin mutation; it never breaks a write that is already in the database.
- touchForEsWatermark() : void
- Bumps the entity update timestamp so the watermark sync also sees an admin edit (a second safety net next to the direct reindex). An entity may have no timestamp, so the default is a no-op; a manager overrides it (`ProductSet::setUpdateTime()`, `Article::setUpdateDatetime()`, ...).
Methods
delete()
public
delete(int|array<string|int, int> $id) : Result
Parameters
- $id : int|array<string|int, int>
Return values
Resultsave()
public
save(BaseEntity $entity[, array<string, mixed> $meta = [] ]) : Result
Parameters
- $entity : BaseEntity
- $meta : array<string, mixed> = []
Return values
ResultupdateColumn()
public
updateColumn(int|array<string|int, int> $entityId, string $property, mixed $value) : Result
Parameters
- $entityId : int|array<string|int, int>
- $property : string
- $value : mixed
Return values
ResultupdateColumns()
public
updateColumns(int|array<string|int, int> $entityId, array<string, mixed> $values) : Result
Parameters
- $entityId : int|array<string|int, int>
- $values : array<string, mixed>
Return values
ResultesReindexBestEffort()
Catches ES up after an admin mutation; it never breaks a write that is already in the database.
protected
esReindexBestEffort(array<string|int, int> $ids) : void
Parameters
- $ids : array<string|int, int>
touchForEsWatermark()
Bumps the entity update timestamp so the watermark sync also sees an admin edit (a second safety net next to the direct reindex). An entity may have no timestamp, so the default is a no-op; a manager overrides it (`ProductSet::setUpdateTime()`, `Article::setUpdateDatetime()`, ...).
protected
touchForEsWatermark(BaseEntity $entity) : void
Parameters
- $entity : BaseEntity