Skip to main content
The Search add-on provides a query layer on top of the search indexes described in the Search reference. It wraps Laravel Scout and adds support for faceted search, filtering, sorting, and consistent response formatting using Spatie Laravel Data.

Supported Engines

The Meilisearch and Typesense PHP clients ship as dependencies of this add-on, so both drivers are available once the add-on is installed. Meilisearch also has a separate, optional add-on (see Meilisearch below) that configures index settings — it is not required to query Meilisearch through this add-on.

Installation

Require the Composer package

The package auto-discovers its Lunar\Search\SearchServiceProvider, so no additional registration is needed.

Configuration

The add-on ships its own facets configuration, merged under the same lunar.search key used by the core search config:
This config is merged, not published — there is no vendor:publish tag for it. To override or extend it, create config/lunar/search.php in the host application; any keys not present there fall back to the add-on’s defaults. The engine_map and models keys read by the core search config (see the Search reference) live in the same file. Each key under a model’s facets entry corresponds to a field in that model’s searchable index. The value is an array of per-facet-value configuration, used to attach extra data (such as a hex color) to a specific value:
label is optional and defaults to the field name. Additional keys per facet value (like hex_value above) are merged into the corresponding SearchFacetValue in the response.
engine_map, which controls which search driver is used for each model, is defined in the core Lunar search config. See the Search reference for details.

Usage

Search models using the Search facade. By default, searches are performed against Lunar\Core\Models\Product:
Search resolves to Lunar\Search\SearchManager, an Illuminate\Support\Manager. Query methods such as query(), filter(), sort(), and get() are defined on the underlying engine (Lunar\Search\Engines\AbstractEngine), not on the manager itself — calling them on the Search facade forwards the call to the resolved driver automatically. To search a different model, use the model() method:
The package detects which Scout driver is mapped for the given model via the engine_map configuration and performs the search using that driver. Results are not hydrated from the database — the raw indexed data is returned directly from the search provider.

Specifying a Driver

To explicitly use a specific search driver, call the driver() method:

Filtering

Apply filters to narrow down search results. Filters are passed as key-value pairs where the key is the field name and the value is the filter value:
Facets allow users to refine search results by selecting values within categories (e.g., brand, color, size). Set active facet selections using setFacets():
The search response includes updated facet counts that reflect the current selections, so the storefront can show how many results match each facet value. To remove a specific facet or value:

Sorting

Sort results by a specific field:
The sort format is field:direction, where direction is asc or desc. The field must be configured as sortable on the model’s indexer (see the Search reference). For Typesense, a raw sort expression can also be used:

Pagination

Control the number of results per page using the perPage() method. The default is 50:

Extending Queries

For advanced use cases, extend the search query using extendQuery():

Response Format

All search engines return a Lunar\Search\Data\SearchResults object with a consistent structure:

SearchHit

Each hit contains the indexed document data and any highlights (Typesense only):

SearchHitHighlight

SearchFacet

SearchFacetValue

Handling the Response

Displaying Results

Displaying Facets

Pagination

The links property contains a standard Laravel pagination view:

Accessing Pagination Metadata

TypeScript Integration

Every response class in Lunar\Search\Data is annotated with Spatie’s #[TypeScript] attribute. If Spatie TypeScript Transformer is being used, add the add-on’s data path to the typescript-transformer.php config to generate TypeScript types for the search response classes:
The generated types are available under the Lunar.Search namespace:

Meilisearch

Meilisearch needs to know which indexed fields are filterable and sortable before it can serve faceted queries. This is a one-time (or per-schema-change) setup step, separate from running searches:
This add-on has no configuration of its own and provides a single Artisan command:
It reads config('lunar.search.models'), creates any missing Meilisearch indexes, and applies each model’s filterable and sortable attributes (as defined by its indexer — see the Search reference) to the corresponding index.
The Meilisearch and Typesense engines used to query results live in the lunarphp/search package installed above. The lunarphp/meilisearch add-on only configures Meilisearch’s index settings; it is not required to run Meilisearch queries through the Search facade.

Typesense

Typesense is available as a driver (Lunar\Search\Engines\TypesenseEngine) once lunarphp/search is installed, with no separate add-on package required. Configure Typesense’s own collection schema and search parameters through Scout’s config/scout.php (the typesense.model-settings key), which controls field types for filtering, highlight and hybrid search settings, and query defaults.