Install the Bundle & Adapter
composer require cmsig/seal-symfony-bundle cmsig/seal-elasticsearch-adapter
(Replace elasticsearch-adapter with your preferred adapter, e.g., memory-adapter for testing.)
Enable the Bundle
Add to config/bundles.php:
return [
// ...
Cmsig\SealBundle\SealBundle::class => ['all' => true],
];
Configure the Adapter
Define your adapter in config/packages/seal.yaml:
seal:
adapter: elasticsearch
elasticsearch:
host: 'localhost'
port: 9200
First Use Case: Basic Search
Inject the SealClient service and execute a query:
use Cmsig\SealBundle\Client\SealClientInterface;
class MyController
{
public function __construct(private SealClientInterface $sealClient) {}
public function search(Request $request)
{
$query = $this->sealClient->query()
->addText('title', $request->query->get('q'))
->execute();
return $this->json($query->getResults());
}
}
config/packages/seal.yaml (Adapter-specific configurations).src/Client/SealClientInterface (API contract for queries).Query Building Chain methods for complex queries:
$query = $this->sealClient->query()
->addText('content', 'laravel')
->addFilter('category', 'tutorial')
->setPage(2, 10)
->sort('published_at', 'desc');
Index Management
Define indexes via YAML (e.g., config/packages/seal_indexes.yaml):
seal:
indexes:
articles:
adapter: elasticsearch
settings:
analyzer: 'english'
mappings:
title: { type: 'text' }
content: { type: 'text' }
Register indexes programmatically:
$this->sealClient->index('articles')->create();
Event-Driven Indexing Use Symfony events to sync data (e.g., after entity persistence):
// In a listener
$this->sealClient->index('articles')->addDocument($article->toArray());
Dependency Injection Bind custom adapters or services:
# config/services.yaml
services:
App\Service\CustomSealAdapter:
arguments:
- '@seal.client'
cmsig/seal-doctrine-adapter to auto-index entities.JsonResponse.SealClientInterface with cmsig/seal-memory-adapter for unit tests.Adapter-Specific Quirks
settings and mappings against Elasticsearch schema.Query Performance
addText() fields without analyzer or search_analyzer.addFilter() for exact matches (e.g., categories) to reduce query load.Configuration Overrides
seal.yaml override defaults. Use !import to merge:
seal:
!import '@seal/config.yaml'
indexes:
articles: { settings: { ... } }
Debugging
config/packages/monolog.yaml:
handlers:
seal:
type: stream
path: '%kernel.logs_dir%/seal.log'
level: debug
$query->getRawQuery(); // Returns adapter-specific query object
Custom Adapters
Implement Cmsig\Seal\Adapter\AdapterInterface and register via:
seal:
adapters:
custom:
class: App\Adapter\CustomSealAdapter
arguments: ['@service_id']
Query Transformers
Extend Cmsig\Seal\Query\QueryBuilder to add domain-specific methods:
class AppQueryBuilder extends QueryBuilder
{
public function addFuzzyText(string $field, string $value): self
{
return $this->addText($field, $value)->setFuzziness(2);
}
}
Bind in services.yaml:
services:
App\Query\AppQueryBuilder: ~
Event Listeners
Subscribe to seal.index.created or seal.query.executed events:
// src/EventListener/SealListener.php
public static function getSubscribedEvents(): array
{
return [
'seal.query.executed' => 'onQueryExecuted',
];
}
index()->addDocuments([...]) for batch inserts.setPage() and getTotalResults() for UI controls.How can I help you explore Laravel packages today?