Which tool to choose to use Elasticsearch in a Symfony project
How to use Elasticsearch in a Symfony project? Which librairy or bundle to choose? I often read these questions on community slack. I'm not going to write a complete guide, but I give you my point of view on different tools I used in the past or still use.
I discovered Elasticsearch during a workshop at ForumPHP conf in 2014, and I'm using it since 2016 on this blog, on a high traffic webshop, on business application to create dashbaord...
Elasticsearch provides a REST API to manage indices and their content or query the data. So it's possible to use Elasticsearch with a simple client like HttpClient component of Symfony and not need to add any dependancy. In this case, we need to manage ourself the connection to the cluster, knowing all the endpoints of the API and follow every Elasticsearch update/changelog to update our code. I don't think it's a good choice even for small project, it involves a lot of maintenance like when Elasticsearch removed multi type, then type support in index.
The Elasticsearch-PHP library
The elasticsearch-php library is a simple client for using Elasticsearch. It abstracts endpoints from the Elasticsearch API and simplifies the connection to the cluster. In addition, this library is maintained by the Elasticsearch team, so it follows the updates as closely as possible.
Its use is easy, you just have to give it the documents to index in JSON format or in an associative array. To make a query on the index, it's the same as a JSON or an associative array. The response are in the form of an associative array.
This library is my default choice. I'm used to using JSON in requests, so I can easily build and debug them in Kibana. This approach also allows me to learn the structure of requests. I wrote an post on this blog to use this Elasticsearch client in a Symfony project using Twig.
To stay oriented object approach, all you have to do is use Symfony's Serializer component to transform API responses into an object. Here too, I usually use the Symfony\Component\Serializer\Normalizer\DeNormalizableInterface interface which allows me to put as close as possible the denormalization logic to reconstruct sometimes complex data coming from several aggregates when I work on dashbaord.
The Rufflin Elastica library
The elasticsearch-php library coupled with Twig is suitable when queries on the index are fixed. That is to say when you only change values.
If there is a need to build a query dynamically, doing so with Twig would make the template quickly unreadable and difficult to maintain and I don't think using an associative array is better.
In this case, the Elastica library offers object abstraction for building Elasticsearch queries, much like Doctrine's QueryBuilder. I use it on an ecommerce site to manage the search with the filters selected by the user.
In the background, Elastica uses the elasticsearch-php library, so it is possible to mix the 2 approaches using the abstraction proposed by Elastica in addition to a simpler approach. It also allows you to easily upgrade from elasticsearch-php to Elastica if the need arises.
The Friend Of Symfony Elastica bundle
This bundle comes up very often in discussions and I think it's the first choice for developers new to Elasticsearch.
It offers an integration of the Elastica library in Symfony. But above all, it offers a “magic” management of indexed documents in Elasticsearch by coupling to Doctrine entities through the latter's lifecycle events.
On paper it sounds sexy, but in the end we often end up with documents that look like entities, which is a mistake. I've always denormalized the content I index in ES to fit my queries and I use multiple indexes if needed.
Another problem is the lack of control over the timing of indexation. Using asynchronous to reduce page response time is not native. And if you want to reindex everything following a mapping change, you have to go through a command that will iterate over the entire database. We all know the performance problems of ORMs on large volumes, I let you imagine the re-indexing of an ecommerce catalog of 5 million items.
And the last negative point is the update of this bundle with respect to Elasticsearch or Symfony, it usually takes time and blocks the update of the project.
I'm not going to talk about all the solutions that exist, there are others like Elastically proposed by Jolicode that adds functionality to the Elastica library. I hope this article will answer the questions that devs have when considering starting to use Elasticsearch with Symfony.