Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Search multi indexes for multi-language results #227

xantos05 opened this issue Feb 3, 2013 · 9 comments

Search multi indexes for multi-language results #227

xantos05 opened this issue Feb 3, 2013 · 9 comments


Copy link

xantos05 commented Feb 3, 2013

I've created a multi-lingual website with Symfony2 using the (Gedmo) Translatable behavior extension for Doctrine2. This works fine but now i'm looking for a way to use the ElasticaBundle to create a nice searchoption. I want German users to search in the German-translation but also in the English translation.

At the moment i'm trying to use separate indexes for each language. My config.yml looks like this:

        default: { host: localhost, port: 9200 }    
                    name: { boost: 5, analyzer: my_analyzer }                                                                         
                    driver: orm
                    model:  Test\SiteBundle\Entity\Article
                    identifier: id
                        service: elastica.translation.provider.article.en                        

This works fine if you want to search through one index but searching two indexes seems not possible with this bundle or am I wrong?

Is there a way to do this? Any help will be appreciated!


Copy link

I had kind of the same problem but with projects instead of articles. I just made one index, in your case this would be called "article".
Then in a custom provider I would add an article to your index for every language. The id for the elastic document you add would then be "$article->getId() .'_' . $article->getTranslatableLocale()" (Look at the gedmo translatable extension documentation for this last method).

Then the hard part, mapping your elastica search results to the model (since you got a custom id, you got to add a custom mapper).

Extend the existing mapper class and add the following method:

protected function findByIdentifiers(array $identifierValues, $hydrate)
        if (empty($identifierValues)) {
            return array();

        foreach($identifierValues as $key => $value){
            $identifierValues[$key] = current(explode("_", $value));

        $hydrationMode = $hydrate ? Query::HYDRATE_OBJECT : Query::HYDRATE_ARRAY;
        $qb = $this->registry
        /* @var $qb \Doctrine\ORM\QueryBuilder */
        $qb->where($qb->expr()->in('o.'.$this->options['identifier'], ':values'))
            ->setParameter('values', $identifierValues);

        return $qb->getQuery()->setHydrationMode($hydrationMode)->execute();

This will take the array with result-identifiers, and cut the _language from them so you have an array of article-id's.

You then add a service for this:
    class: Article
    arguments: [@doctrine, ArticleBundle\Entity\Article, [identifier: id, hydrate: true]]

and put the following in your search-config:


You can then search for articles in multiple languages.

Copy link

ibasaw commented Jun 24, 2013

is there a simple way to do this ?

In ES, you can search on multiples indexes /types at same time.

Copy link

Would be cool to have some kind of pointer about the way to go...

@merk merk added this to the 3.1.0 milestone Jul 12, 2014
Copy link

+1 on this, better solution for searching translatable entities would be much appriciated

Copy link

+1, wait better solution

Copy link

raistlin commented Aug 5, 2015

+1, Still no solution here?

Copy link

The problem of working with a custom provider, is that the listener is not working anymore.

A better solution would be to write a custom ObjectPersister and let the persister to the "duplication". The elastica_to_model_transformer is still necessary, because you need composite ES identifiers.

Copy link

maxpou commented Feb 10, 2016

I got the same problem.
So, I choose an other service : fos_elastica.client. Anyway, I had no choice because my finders didn't work...

Here's a part of my solution:

use Elastica\Request as ElasticaRequest;


$userQuery = "bob";
$client = $this->container->get('fos_elastica.client');
$query = array(
    'query' => array(
        'query_string' => array(
            'query' => $userQuery,
    'from' => '6',  //optional (default 0)
    'size' => '5'   //optional (default 10)

$results = $client->request('/myIndex/_search', ElasticaRequest::GET, $query);
$results->getData(); //Elasticsearch JSON response

Further more reading :

Copy link

tuxado commented Apr 16, 2016

i have use nested to translations like that come directly from the entity :

                        type: nested
                        properties :
                            name: ~
                            locale: ~
                            description: ~


"_index": "index",
"_type": "book",
"_id": "1",
"_version": 1,
"_score": 1,
"_source": {
"translations": [
"name": "....",
"locale": "en",
"description": "...."
and i use the nested query to search using bool with must locale : "en"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
None yet
None yet

No branches or pull requests