Installation:
composer require friendsofsymfony/elastica-bundle
Add to config/bundles.php:
return [
// ...
FriendsOfSymfony\ElasticaBundle\FOSElasticaBundle::class => ['all' => true],
];
Configure Elasticsearch Client (config/packages/fos_elastica.yaml):
fos_elastica:
clients:
default: { host: localhost, port: 9200 }
indexes:
app:
types:
product:
properties:
name: ~
price: ~
persistence:
driver: orm
model: App\Entity\Product
provider: ~
listener: ~
repository: ~
First Use Case:
php bin/console fos:elastica:populate
$repository = $this->getDoctrine()
->getRepository(Product::class)
->getElasticaRepository();
$results = $repository->find('search_term');
Automatic Indexing:
prePersist, preUpdate, preRemove) to sync Elasticsearch with your database.fos_elastica:
indexes:
app:
types:
product:
persistence:
listener: true # Auto-index on Doctrine events
Custom Mappings:
properties:
name:
type: text
analyzer: custom_analyzer
@Elastica\Property in entities:
use FOSElasticaBundle\Elastica\Annotation as Elastica;
/**
* @Elastica\Property(type="integer")
*/
private $stock;
Search Integration:
$query = new \Elastica\Query\Match();
$query->setFieldQuery('name', 'search_term');
$results = $repository->search($query);
$aggregation = new \Elastica\Aggregation\Terms('categories');
$aggregation->setField('category');
$results = $repository->search(new \Elastica\Query(), $aggregation);
Bulk Operations:
fos:elastica:populate for initial indexing.php bin/console fos:elastica:reindex
Pagination:
setFrom() and setSize() in queries:
$query->setFrom(0)->setSize(10);
Symfony Forms:
$builder->add('name', EntityType::class, [
'class' => Product::class,
'query_builder' => function (ProductRepository $repo) {
return $repo->createElasticaQueryBuilder('search_term')->select('p');
},
]);
APIs:
#[Route('/search', name: 'app_search', methods: ['GET'])]
public function search(Request $request, ProductElasticaRepository $repo): JsonResponse
{
$query = new \Elastica\Query\Match();
$query->setFieldQuery('name', $request->query->get('q'));
$results = $repo->search($query);
return new JsonResponse($results);
}
Cron Jobs:
php bin/console fos:elastica:reindex --env=prod
Mapping Conflicts:
php bin/console fos:elastica:reindex
Listener Overhead:
save(), which can slow down bulk operations.$em->getEventManager()->removeEventListeners('prePersist');
// Bulk operations...
$em->getEventManager()->addEventListeners('prePersist');
Pagination Limits:
from=0 and size=10 for pagination. Large offsets (from) are inefficient.search_after for deep pagination or implement keyset pagination.Case Sensitivity:
keyword fields:
properties:
sku:
type: keyword # Exact matches
Propel Support:
Check Index Status:
curl -XGET 'http://localhost:9200/_cat/indices?v'
Inspect Mappings:
curl -XGET 'http://localhost:9200/app/_mapping?pretty'
Enable Debugging:
config/packages/dev/fos_elastica.yaml:
fos_elastica:
clients:
default:
debug: true
Log Queries:
Logger:
$client->getLogger()->setLevel(\Psr\Log\LogLevel::DEBUG);
Custom Providers:
Persistence\Provider\AbstractProvider to fetch data from non-Doctrine sources (e.g., APIs).Event Subscribers:
fos_elastica.index events:
$eventDispatcher->addListener(
'fos_elastica.index',
function (IndexEvent $event) {
$event->getDocument()->setData('custom_field', 'value');
}
);
Query Builders:
class CustomQueryBuilder extends \FOSElasticaBundle\Elastica\QueryBuilder
{
public function withCustomFilter()
{
$this->addFilter(new \Elastica\Filter\Term('status', 'active'));
return $this;
}
}
Serializer Groups:
fos_elastica:
indexes:
app:
types:
product:
persistence:
serializer:
groups: ['elastica']
How can I help you explore Laravel packages today?