Поскольку документация FOSElasticaBundle не очень точная, я просмотрел ее код и не смог контролировать, какой конструктор запросов используется на уровне контроллера.
Можно изменить весь elastica_to_model_transformer
на персонализированную службу, но все же она статически определена в конфигурации. Может быть, с каким-то грязным решением это будет возможно, но я не думаю, что это того стоит.
Я решил не использовать эту функцию FOSElasticaBundle. Основная проблема, с которой я столкнулся, заключалась в том, что при использовании fos_elastica.index
вместо fos_elastica.finder
или репозитория для эластичных (для получения простых результатов нет Elastica\Resultset
) нет метода findPaginated
с возвратом Pagerfanta
объект-указатель, что очень полезно в моем случае.
К счастью, хотя это не указано в документации, возможно также создать Pagerfanta
, но немного более вручную.
Вот фрагмент кода:
//generate ElaticaQuery somehow.
$browseQuery = $browseData->getBrowseQuery();
$search = $this->container->get('fos_elastica.index.indexName.typName');
//create pagerfanta's adapter manually
$adapter = new \Pagerfanta\Adapter\ElasticaAdapterElasticaAdapter($search, $browseQuery);
// now you can create the paginator too.
$pager = new Pagerfanta($adapter);
//do some paging work on it...
$pager->setMaxPerPage($browseData->getPerPage());
try {
$pager->setCurrentPage($browseData->getPage());
} catch(OutOfRangeCurrentPageException $e) {
$pager->setCurrentPage(1);
}
//and get current page results.
/** @var Result[] $elasticaResults */
$elasticaResults = $pager->getCurrentPageResults();
// we have to grab ids manyally, but it's done the same way inside FOSElasticaBundle with previous approach
$ids = array();
foreach($elasticaResults as $elasticaResult) {
$ids[] = $elasticaResult->getId();
}
//use regular Doctrine's repository to fetch Entities any way you want.
$entities = $this->getDoctrine()->getRepository(MyEntity::class)->findByIdentifiers($ids);
Это на самом деле имеет несколько преимуществ. В общем, он дает вам контроль над вашими данными и не связывает ElasticSearch с Doctrine. Поэтому вы можете уйти в отставку при извлечении данных из Doctrine, если у вас есть все необходимые данные в ElasticSearch (если они, конечно, являются данными только для чтения). Это позволяет оптимизировать производительность вашего приложения, но уменьшая количество SQL-запросов.
Код, указанный выше, может быть обернут каким-то обслуживанием, чтобы предотвратить беспорядок в контроллерах.