Skip to main content
Lunar indexes its core models through Laravel Scout, giving every store a working search index out of the box that can be swapped onto a dedicated search engine as needed.

Overview

Search indexing in Lunar core is built on Laravel Scout. Scout’s database driver provides basic search with no extra services to run, while engines such as Meilisearch can be used instead for faster, more capable search. All search configuration lives in config/lunar/search.php. This file controls which models are indexed, which search engine each model uses, and which indexer class prepares the data for each model.
For building storefront search with faceted filtering, sorting, and structured results on top of these indexes, see the Search add-on.

Configuration

Publish the config file with:

Soft Deletes

By default, Scout sets the soft_delete option to false. Set this to true in config/scout.php so that soft-deleted models are excluded from search results.

Searchable Models

The models array in config/lunar/search.php defines which models are indexed. Lunar registers the following models by default:
To index a custom model, append it to this array. The model must use the Lunar\Core\Models\Concerns\Searchable trait.

Engine Mapping

By default, Scout uses the driver defined by the SCOUT_DRIVER environment variable for every model. This means that if SCOUT_DRIVER is set to meilisearch, every searchable model is indexed via Meilisearch. This is not always desirable. For example, indexing orders in a paid service alongside products unnecessarily increases record counts and cost. The engine_map configuration key sets a different driver per model:
Any model not listed in engine_map falls back to the default Scout driver.

The Searchable Trait

Every searchable Lunar model uses the Lunar\Core\Models\Concerns\Searchable trait, which wraps Scout’s own Searchable trait and delegates behavior to a resolved indexer instance:
  • searchableAs() — returns the index name
  • toSearchableArray() — returns the data to index
  • shouldBeSearchable() — determines whether the model should be indexed
  • searchableUsing() — returns the engine, resolved from the engine_map configuration
  • getFilterableAttributes() — returns filterable fields for the engine
  • getSortableAttributes() — returns sortable fields for the engine
  • getScoutKey() / getScoutKeyName() — the key and key name used to index the model
  • makeAllSearchableUsing() — modifies the query used when bulk-importing the model
The trait resolves the indexer for a model from config('lunar.search.indexers'), falling back to the base Lunar\Core\Search\ScoutIndexer if the model has no dedicated entry.

Indexers

Each searchable model is paired with an indexer class implementing Lunar\Core\Search\Interfaces\ScoutIndexerInterface, which controls what data is sent to the search engine and which of those fields are sortable or filterable. The indexers config maps models to their indexer:

Default Indexer

Lunar\Core\Search\ScoutIndexer is the base indexer, used for any model not listed in indexers. It indexes:
  • The model’s id
  • Any custom attributes marked as searchable, via Lunar\Core\Facades\AttributeManifest::getSearchableAttributes()
Translatable attribute values (Lunar\Core\FieldTypes\TranslatedText) are exploded into locale-suffixed keys (for example name_en, name_fr) rather than indexed as a single field. Sortable fields: created_at, updated_at Filterable fields: __soft_deleted

Product Indexer

Lunar\Core\Search\ProductIndexer indexes the following fields: Sortable fields: created_at, updated_at, skus, status Filterable fields: __soft_deleted, skus, status

Order Indexer

Lunar\Core\Search\OrderIndexer indexes the following fields: Sortable fields: customer_id, user_id, channel_id, created_at, updated_at, closed_at, total Filterable fields: customer_id, user_id, payment_status, fulfilment_status, closed, placed_at, channel_id, tags
The Table Rate Shipping add-on adds a shipping_zone field to the order index when it is installed.

Customer Indexer

Lunar\Core\Search\CustomerIndexer indexes the following fields: Sortable fields: created_at, updated_at, name, company_name Filterable fields: __soft_deleted, name, company_name

Brand Indexer

Lunar\Core\Search\BrandIndexer indexes the following fields: Sortable fields: created_at, updated_at, name Filterable fields: __soft_deleted, name

Collection Indexer

Lunar\Core\Search\CollectionIndexer indexes the same shape of data as the Brand indexer: id, public_id, created_at, the translatable name/description/short_description columns exploded per locale, and searchable custom attribute values. Sortable fields: created_at, updated_at, name Filterable fields: __soft_deleted, name

ProductOption Indexer

Lunar\Core\Search\ProductOptionIndexer indexes the following fields: Sortable fields: created_at, updated_at Filterable fields: __soft_deleted

Custom Indexers

To customize what data is indexed for a model, implement Lunar\Core\Search\Interfaces\ScoutIndexerInterface (or extend Lunar\Core\Search\ScoutIndexer) and map the model to it under the indexers key in config/lunar/search.php:

Indexing Records

To import or refresh search indexes, use the lunar:search:index Artisan command:
This imports every model listed in the models configuration, using Scout’s scout:import and scout:flush commands under the hood.

Command Options

Meilisearch

Configuring Meilisearch as the Scout driver makes Lunar’s indexers write data suitable for facet and sort filtering, but Meilisearch also needs to know which fields on each index are filterable and sortable. The Meilisearch add-on provides a lunar:meilisearch:setup command that reads each model’s getFilterableAttributes() and getSortableAttributes() (both defined by the indexer) and applies them to the corresponding Meilisearch index. The fields, sortable attributes, and filterable attributes documented above are what a search engine sees once a model is indexed. To query them from a storefront, with support for faceted filtering, sorting, pagination, and Typesense as well as Meilisearch, install the Search add-on.