Skip to main content
The official meilisearch-symfony bundle provides seamless integration between Meilisearch and Symfony applications with Doctrine ORM support.

Prerequisites

  • PHP 7.4 or higher
  • Symfony 5.4 or higher
  • Doctrine ORM (optional, for automatic entity indexing)
  • A Meilisearch instance (Cloud or self-hosted)

1. Install the bundle

composer require meilisearch/search-bundle

2. Configure the bundle

Create or update config/packages/meilisearch.yaml:
meilisearch:
  url: '%env(MEILISEARCH_URL)%'
  api_key: '%env(MEILISEARCH_API_KEY)%'
Add to your .env file:
MEILISEARCH_URL=https://your-instance.meilisearch.io
MEILISEARCH_API_KEY=your_api_key

3. Configure an entity for indexing

Add the Searchable attribute to your Doctrine entity:
<?php

namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;
use Meilisearch\Bundle\Searchable;

#[ORM\Entity]
#[Searchable(indexName: 'movies')]
class Movie
{
    #[ORM\Id]
    #[ORM\GeneratedValue]
    #[ORM\Column]
    private ?int $id = null;

    #[ORM\Column(length: 255)]
    private ?string $title = null;

    #[ORM\Column]
    private ?int $year = null;

    #[ORM\Column(type: 'json')]
    private array $genres = [];

    // Getters and setters...

    // Define which fields to index
    public function getSearchableArray(): array
    {
        return [
            'id' => $this->id,
            'title' => $this->title,
            'year' => $this->year,
            'genres' => $this->genres,
        ];
    }
}

4. Index your data

Import existing entities to Meilisearch:
php bin/console meilisearch:import
New entities are automatically indexed when created or updated via Doctrine. Use the SearchService to search your indexed entities:
<?php

namespace App\Controller;

use Meilisearch\Bundle\SearchService;
use App\Entity\Movie;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;

class SearchController extends AbstractController
{
    #[Route('/search', name: 'search')]
    public function search(SearchService $searchService): Response
    {
        $results = $searchService->search(
            Movie::class,
            'matrix'
        );

        return $this->render('search/results.html.twig', [
            'movies' => $results,
        ]);
    }
}

6. Search with filters

First, configure filterable attributes in config/packages/meilisearch.yaml:
meilisearch:
  url: '%env(MEILISEARCH_URL)%'
  api_key: '%env(MEILISEARCH_API_KEY)%'
  indices:
    - name: movies
      class: App\Entity\Movie
      settings:
        filterableAttributes: ['genres', 'year']
        sortableAttributes: ['year']
Update the index settings:
php bin/console meilisearch:create
Then search with filters:
$results = $searchService->search(
    Movie::class,
    'action',
    [
        'filter' => 'year > 2000',
        'sort' => ['year:desc'],
    ]
);

Available commands

CommandDescription
meilisearch:importImport all entities to Meilisearch
meilisearch:clearClear all indexed data
meilisearch:createCreate indexes with configured settings
meilisearch:deleteDelete indexes

Raw client access

For advanced operations, access the Meilisearch client directly:
use Meilisearch\Client;

class MyService
{
    public function __construct(private Client $client) {}

    public function customOperation(): void
    {
        $index = $this->client->index('movies');
        $stats = $index->getStats();
    }
}

Next steps

Full-text search

Configure ranking and relevancy

Filtering

Add filters and facets

AI-powered search

Add semantic search

API reference

Explore all search parameters

Resources