FOSElasticaBundle icon indicating copy to clipboard operation
FOSElasticaBundle copied to clipboard

Search without hydration through fos.elastical.finder.*

Open spiroski opened this issue 5 years ago • 2 comments

Hello,

Is it possible to search without hydrating ( Transforming ) the results with a finder?

In my case, I would like to only get the ids ( Avoid querying the database ).

If it is not possible, I believe it is very useful to introduce this feature.

spiroski avatar Aug 28 '20 18:08 spiroski

Here's how I solved that problem, though I don't think it's elegant.
Anyway, you need to create a transformer service:

<?php

namespace App\Transformers;

use Doctrine\Common\Persistence\ManagerRegistry;
use FOS\ElasticaBundle\Doctrine\ORM\ElasticaToModelTransformer;

class ElasticaToArticleIdTransformer extends ElasticaToModelTransformer
{
    public function __construct(ManagerRegistry $registry, string $objectClass='NOT USED', array $options = [])
    {
        parent::__construct($registry, $objectClass, $options);
    }

    protected function findByIdentifiers(array $identifierValues, $hydrate): array
    {
        return empty($identifierValues) ? [] : array_map(fn($aId) => ['id' => (int)$aId], $identifierValues);
    }
}

Then in fos_elastica.yaml, set the elastica_to_model_transformer service.

fos_elastica:
  clients:
    default: { url: '%env(ELASTICSEARCH_URL)%' }
  indexes:
    article:
      persistence:
        driver: orm
        elastica_to_model_transformer:
          service: App\Transformers\ElasticaToArticleIdTransformer
          hydrate: false
        model:  App\Entity\Article

You'll get back an array of arrays containing just the ids.

tacman avatar Sep 22 '20 13:09 tacman

Here's how I solved that problem, though I don't think it's elegant. Anyway, you need to create a transformer service:

<?php

namespace App\Transformers;

use Doctrine\Common\Persistence\ManagerRegistry;
use FOS\ElasticaBundle\Doctrine\ORM\ElasticaToModelTransformer;

class ElasticaToArticleIdTransformer extends ElasticaToModelTransformer
{
    public function __construct(ManagerRegistry $registry, string $objectClass='NOT USED', array $options = [])
    {
        parent::__construct($registry, $objectClass, $options);
    }

    protected function findByIdentifiers(array $identifierValues, $hydrate): array
    {
        return empty($identifierValues) ? [] : array_map(fn($aId) => ['id' => (int)$aId], $identifierValues);
    }
}

Then in fos_elastica.yaml, set the elastica_to_model_transformer service.

fos_elastica:
  clients:
    default: { url: '%env(ELASTICSEARCH_URL)%' }
  indexes:
    article:
      persistence:
        driver: orm
        elastica_to_model_transformer:
          service: App\Transformers\ElasticaToArticleIdTransformer
          hydrate: false
        model:  App\Entity\Article

You'll get back an array of arrays containing just the ids.

The problem is that in most cases I do need the models hydrated, only in certain cases I don't ( where I want to reuse a search result for another search or something like that ).

spiroski avatar Sep 25 '20 10:09 spiroski