SearchIndexableReadModel - viames/pair GitHub Wiki

Pair framework: SearchIndexableReadModel

Pair\Search\SearchIndexableReadModel is the small contract for read models that can publish a search-specific document shape.

It extends ReadModel, so the same object can keep one API-facing representation through toArray() and one search-facing representation through searchDocument().

Contract

use Pair\Search\SearchIndexableReadModel;

final readonly class ProductReadModel implements SearchIndexableReadModel {

	/**
	 * Build the product read model.
	 */
	public function __construct(
		public int $id,
		public string $title,
		public bool $active,
		public string $category
	) {}

	/**
	 * Return the default Meilisearch index UID for products.
	 */
	public static function searchIndexUid(): string {
		return 'products';
	}

	/**
	 * Return the primary key field for indexed products.
	 */
	public static function searchPrimaryKey(): string {
		return 'id';
	}

	/**
	 * Export the public API representation.
	 *
	 * @return	array<string, mixed>
	 */
	public function toArray(): array {
		return [
			'id' => $this->id,
			'title' => $this->title,
		];
	}

	/**
	 * Export the search-specific document representation.
	 *
	 * @return	array<string, mixed>
	 */
	public function searchDocument(): array {
		return [
			'id' => $this->id,
			'title' => $this->title,
			'is_active' => $this->active,
			'category' => $this->category,
		];
	}

}

Why it exists

Search indexes often need fields that should not be returned directly from JSON APIs, such as denormalized flags, category labels, tenant filters, or searchable text bundles.

Keeping toArray() and searchDocument() separate makes that boundary explicit.

Methods

  • searchIndexUid(): string
  • searchPrimaryKey(): string
  • searchDocument(): array

MeilisearchClient::indexReadModels(...) uses these methods when the read model implements this contract.

See also: MeilisearchClient, ReadModel, RecordMapper, Integrations.