FOSElasticaBundle
FOSElasticaBundle copied to clipboard
Multiple index paginated search
I'm looking for solution to search through multiple indices, and in the same time be able to get paginated result.
I found here https://github.com/FriendsOfSymfony/FOSElasticaBundle/issues/1385 that it's possible to search in multiple indices, but it's different approach than using finder, where you can just do findPaginated and get paginated results back.
Is it possible somehow to get paginated results searching in multiple indices.
I'm interested too !
full article here: https://www.exploit.cz/how-to-search-across-multiple-elasticsearch-indexes-with-symfony-fos-elasticabundle/
solution based on code in #1385
define service
FOS\ElasticaBundle\Transformer\ElasticaToModelTransformerCollection:
arguments:
- {
recipe: '@fos_elastica.elastica_to_model_transformer.recipe.recipe',
recipes: '@fos_elastica.elastica_to_model_transformer.recipes.recipes'
}
define custom class and inject this collection into $this->elasticaToModelTransformerCollection;
$index = $this->indexManager->getIndex('recipe');
$index2 = $this->indexManager->getIndex('recipes');
$searchable = new MultiIndex($index->getClient(), $index->getName());
$searchable->addIndex($index);
$searchable->addIndex($index2);
$transformer = $this->elasticaToModelTransformerCollection;
$paginatorAdapter = new TransformedPaginatorAdapter($searchable, $query, [], $transformer);
$items = new Pagerfanta(new FantaPaginatorAdapter($paginatorAdapter));
$items->setMaxPerPage($limit);
$items->setCurrentPage($page);
where MultiIndex looks like
<?php
declare(strict_types=1);
/*
* Created by Exploit.cz <[email protected]>
*/
namespace App\Search\Elastica;
use Elastica\Exception\InvalidException;
use Elastica\Index;
use Elastica\ResultSet\BuilderInterface;
use Elastica\Search;
class MultiIndex extends Index
{
/**
* Array of indices.
*
* @var array
*/
protected $_indices = [];
/**
* Adds a index to the list.
*
* @param \Elastica\Index|string $index Index object or string
*
* @throws \Elastica\Exception\InvalidException
*
* @return $this
*/
public function addIndex($index)
{
if ($index instanceof Index) {
$index = $index->getName();
}
if (!is_scalar($index)) {
throw new InvalidException('Invalid param type');
}
$this->_indices[] = (string) $index;
return $this;
}
/**
* Add array of indices at once.
*
* @param array $indices
*
* @return $this
*/
public function addIndices(array $indices = [])
{
foreach ($indices as $index) {
$this->addIndex($index);
}
return $this;
}
/**
* Return array of indices.
*
* @return array List of index names
*/
public function getIndices()
{
return $this->_indices;
}
/**
* @param string|array|\Elastica\Query $query
* @param int|array $options
* @param BuilderInterface $builder
*
* @return Search
*/
public function createSearch($query = '', $options = null, BuilderInterface $builder = null)
{
$search = new Search($this->getClient(), $builder);
$search->addIndices($this->getIndices());
$search->setOptionsAndQuery($options, $query);
return $search;
}
}
The docs are wrong for elasticsearch 6.0 upwards. Is there a plan to update the bundle? At least to update the docs? See also the closed issue https://github.com/FriendsOfSymfony/FOSElasticaBundle/issues/1385, which should have never been closed in my opinion.
My Article updated, works well with latest master 6.0 Beta (need to create new ElasticaToModelTransformerCollection class) https://www.exploit.cz/how-to-search-across-multiple-elasticsearch-indexes-with-symfony-fos-elasticabundle/
@insekticid thank you for your great solution. I am completely new to FOSElasticaBundle, but searching multiple indices is an absolutely necessary feature that seems to be missing out of the box.
@insekticid works like a charm with elastic 7.10.2, thanks!
Note: @insekticid Doesn't work with Elasticsearch >=8.0 and FOSElasticaBundle 6.2.
@czachor sorry, not using FOSElasticaBundle anymore. I switched to @jolicode/elastically