Skip to main content
In this guide, you will see how to set up Laravel Scout to add full-text search, semantic search, and hybrid search to your Laravel application using Meilisearch.

Prerequisites

Before you start, make sure you have the following installed on your machine: You will also need a Laravel application. If you don’t have one, you can create a new one by running the following command:

Installing Laravel Scout

Laravel Scout is the official Laravel package for adding search to Eloquent models. It supports Meilisearch through a dedicated driver. To enable it, navigate to your Laravel application directory and install Scout via Composer:
After installing Scout, you need to publish the Scout configuration file. You can do this by running the following artisan command:
This command should create a new configuration file in your application directory: config/scout.php.

Configuring the Laravel Scout driver

Now you need to configure Laravel Scout to use the Meilisearch driver. First, install the dependencies required to use Scout with Meilisearch via Composer:
Then, update the environment variables in your .env file:

Local development

Laravel’s official Docker development environment, Laravel Sail, comes with a Meilisearch service out-of-the-box. Please note that when running Meilisearch via Sail, Meilisearch’s host is http://meilisearch:7700 (instead of say, http://localhost:7700).
Check out Docker Bridge network driver documentation for further detail.

Running in production

For production use cases, we recommend using a managed Meilisearch via Meilisearch Cloud. On Meilisearch Cloud, you can find your host URL in your project settings.

Making Eloquent models searchable

With Scout installed and configured, add the Laravel\Scout\Searchable trait to your Eloquent models to make them searchable. This trait will use Laravel’s model observers to keep the data in your model in sync with Meilisearch. Here’s an example model:

Choosing which fields to index

To configure which fields to store in Meilisearch, use the toSearchableArray method. You can use this technique to store a model and its relationships’ data in the same document. The example below shows how to store a model’s relationships data in Meilisearch:

Configuring index settings

Meilisearch index settings control how your data is filtered, sorted, and embedded. In Laravel, you configure them in the meilisearch.index-settings option of config/scout.php, using the model class as the key.

Filterable and sortable attributes

Configure which attributes are filterable and sortable:
The example above updates Meilisearch index settings for the Contact model:
  • it makes the organization_id field filterable
  • it makes the name and company_name fields sortable
Semantic and hybrid search use an embedder to turn text into vectors:
  • Semantic search matches documents by meaning instead of keywords.
  • Hybrid search combines full-text and semantic search in a single query.
Semantic and hybrid search require Laravel Scout 11.8 or later.
With Scout, you can choose who generates embeddings: Use Meilisearch-generated embeddings if you want the simplest setup. Use Scout-generated embeddings if you want to reuse the AI providers already configured in your Laravel application. The examples below use an Article model with title and body fields and the Searchable trait.

Option 1: Let Meilisearch generate embeddings

Define an embedder in your index settings. Then, tell Scout which embedder to use with the model-settings option and set driver to meilisearch:
In this mode, Meilisearch generates embeddings for your documents and for search queries. Scout does not add vectors to your documents, so you do not need a toSearchableEmbedding method. The document template controls which fields Meilisearch embeds. Make sure these fields are present in your model’s toSearchableArray output.
Meilisearch supports many embedding providers. See Configure an OpenAI embedder or choose an embedder.

Option 2: Let Scout generate embeddings

In this mode, Scout generates embeddings with the Laravel AI SDK and sends them to Meilisearch with your documents. This option requires PHP 8.3 or later. First, install the SDK and configure at least one AI provider in your application:
Then, configure a userProvided embedder with the dimensions of your embedding model. Set the same number of dimensions in model-settings:
By default, Scout uses your default Laravel AI provider and embedding model. To use a different one, add the optional provider and model keys to the embedding array. Finally, define a toSearchableEmbedding method on your model. It must return either the text Scout should embed or a precomputed embedding array:
Scout also generates the embedding of each search query with the Laravel AI SDK. If you pass your own query vector with the vector option, Scout skips this step.

Applying your index settings

After changing your index settings, run the following command to apply them to Meilisearch:
With Option 1, changing an embedder’s source, model, or documentTemplate may make Meilisearch regenerate the embeddings of all documents. For large indexes, this can take a long time and incur costs with your embedding provider. Read more about automatic embedding generation.With Option 2, Meilisearch never regenerates embeddings. If you change the AI provider, model, or toSearchableEmbedding output, re-import your records so Scout generates new embeddings.

Importing your data

New and updated records are synced to Meilisearch automatically. To import records that already exist in your database, run the scout:import command for each searchable model:
If you configured embedders, importing also embeds your documents. With Option 1, Meilisearch generates the embeddings. With Option 2, Scout generates them. You must import the Article records before running the semantic and hybrid search examples below.
For large datasets, configure a queue so Scout syncs records in the background. Meilisearch always indexes documents asynchronously, so new records may take a moment to appear in search results.

Searching

To search a model, call the search method and retrieve the matching Eloquent models with get:

Filtering and sorting

You can filter and sort results with Scout’s where and orderBy methods. This requires configuring filterable and sortable attributes first:
Semantic search requires an embedder.
Chain the semantic method onto your search query to match documents by meaning only:
Hybrid search requires an embedder.
Chain the hybrid method to combine full-text and semantic results. The first two arguments set the relative weights of each strategy:
Scout converts these weights into Meilisearch’s semanticRatio as semanticWeight / (textWeight + semanticWeight). The example above sends a semanticRatio of about 0.67. Calling semantic() is the same as a semanticRatio of 1.0.

Semantic and hybrid search options

Both semantic and hybrid accept a minSimilarity argument, which Scout sends to Meilisearch as a rankingScoreThreshold. Meilisearch drops results with a lower score:
Semantic and hybrid queries also work with where clauses and pagination. As with full-text search, you must configure your filterable attributes before filtering. Keep these limitations in mind:
  • The search query must not be empty.
  • Weights passed to hybrid must be positive numbers.
  • You cannot pass a custom hybrid key to the options method. Scout sets this parameter for you.

Example usage

You built an example application to demonstrate how to use Meilisearch with Laravel Scout. It showcases an app-wide search in a CRM (Customer Relationship Management) application.
Laravel Scout example application
This demo application uses the following features: Of course, the code is open-sourced on GitHub. 🎉

Next steps

AI-powered search

Learn how hybrid and semantic search work in Meilisearch

Custom hybrid ranking

Tune the balance between keyword and semantic results

Filtering

Add filters and facets to your searches