FOSElasticaBundle icon indicating copy to clipboard operation
FOSElasticaBundle copied to clipboard

Multiple index paginated search

Open vovkin opened this issue 6 years ago • 8 comments

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.

vovkin avatar May 21 '19 11:05 vovkin

I'm interested too !

pascalbeynel avatar Aug 21 '19 09:08 pascalbeynel

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;
    }
}

insekticid avatar Oct 16 '19 13:10 insekticid

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.

michaelKaefer avatar Oct 17 '19 04:10 michaelKaefer

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 avatar Oct 18 '20 13:10 insekticid

@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.

eizemazal avatar Sep 24 '21 10:09 eizemazal

@insekticid works like a charm with elastic 7.10.2, thanks!

ernestwisniewski avatar Oct 05 '21 20:10 ernestwisniewski

Note: @insekticid Doesn't work with Elasticsearch >=8.0 and FOSElasticaBundle 6.2.

czachor avatar Feb 21 '23 13:02 czachor

@czachor sorry, not using FOSElasticaBundle anymore. I switched to @jolicode/elastically

insekticid avatar Mar 13 '23 10:03 insekticid