Skip to main content
This add-on is currently considered an alpha release.

Installation

Require the composer package

composer require lunarphp/search

Usage

Configuration

Most configuration is done via config/lunar/search.php. Here you can specify which facets should be used and how they are displayed.
'facets' => [
    \Lunar\Models\Product::class => [
        'brand' => [
            'label' => 'Brand',
        ],
        'colour' => [
            'label' => 'Colour',
        ],
        'size' => [
            'label' => 'Size',
        ],
        'shoe-size' => [
            'label' => 'Shoe Size',
        ]
    ]
],
At a basic level, you can search models using the provided facade.
use Lunar\Search\Facades\Search;

// Search on a specific model
$results = Search::on(\Lunar\Models\Collection::class)->query('Hoodies')->get();

// Search on Lunar\Models\Product by default.
$results = Search::query('Hoodies')->get();
Under the hood this will detect what Scout driver is mapped under lunar.search.engine_map and then perform a search using that given driver. To increase performance the results will not be hydrated from the database, but instead will be the raw results from the search provider.

Response format

This packages makes use of Spatie Data to transform search results from the provider into consistent responses you can use on your frontend. You can view all available Data classes in the src/Data directory.

Transforming Data classes to Typescript

If you use Spatie Typescript Transformer, you can add the following to your typescript-transformer.php config:
return [
    //...
    'auto_discover_types' => [
        // ...
        \Lunar\Search\data_path(),
    ],
];
Then in your Javascript the data classes will be available under the Lunar.Search namespace.
defineProps<{
    results: Lunar.Search.SearchResults
}>()

Handling the response

Searching returns a Lunar\Data\SearchResult DTO which you can use in your templates:
use Lunar\Search\Facades\Search;
$results = Search::query('Hoodies')->get();
<!-- Loop through results-->
@foreach($results->hits as $hit)
    {{ $hit->document['name'] }}
@endforeach

<!-- Loop through facets -->
@foreach($results->facets as $facet)
<span>
    <strong>{{ $facet->label }}</strong>
    @foreach($facet->values as $facetValue)
        <input type="checkbox" value="{{ $facetValue->value }}" />
        <span
            @class([
                'text-blue-500' => $facetValue->active,
            ])
        >
            {{ $facetValue->label }}
        </span>
        {{ $facetValue->count }}
    @endforeach
</div>
@endforeach