FOSElasticaBundle:是否可以在控制器中更改 "query_builder_method"?
FOSElasticaBundle: Is it possible to change "query_builder_method" in controller?
根据 FOSElasticaBundle documentation 可以将应用程序配置为使用自定义查询生成器方法,如下所示:
user:
persistence:
elastica_to_model_transformer:
query_builder_method: createSearchQueryBuilder
但是可以选择QB方式吗live,比如在控制器操作中?
我希望能够在将 Elastica 结果转换为 Doctrine 实体时控制从数据库中获取的内容。例如。有时我想对某些关系进行急切获取,但默认情况下不能这样做。
由于 FOSElasticaBundle 文档不是很准确,我查看了它的代码,发现无法控制在控制器级别使用的查询生成器。
可以将整个 elastica_to_model_transformer
更改为自定义服务,但它仍然是在配置中静态定义的。也许使用一些肮脏的解决方案可能会采用这种方式,但我认为这不值得。
我决定不使用 FOSElasticaBundle 的这个功能。我遇到的主要问题是,当您使用 fos_elastica.index
而不是 fos_elastica.finder
或 elastica 存储库(为了获得简单的未转换结果 Elastica\Resultset
)时,没有 findPaginated
方法returns Pagerfanta
paginator 对象,这对我来说很有帮助。
幸运的是,虽然文档中没有提到它,但也可以通过这种方式创建 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 联系起来。因此,如果您在 ElasticSearch 中拥有所有需要的数据(当然如果它们是只读数据),您可以放弃从 Doctrine 获取数据。这使您可以优化应用程序性能,同时减少 SQL 查询的数量。
上面的代码可能包含某种服务,以防止在控制器中造成混乱。
根据 FOSElasticaBundle documentation 可以将应用程序配置为使用自定义查询生成器方法,如下所示:
user:
persistence:
elastica_to_model_transformer:
query_builder_method: createSearchQueryBuilder
但是可以选择QB方式吗live,比如在控制器操作中?
我希望能够在将 Elastica 结果转换为 Doctrine 实体时控制从数据库中获取的内容。例如。有时我想对某些关系进行急切获取,但默认情况下不能这样做。
由于 FOSElasticaBundle 文档不是很准确,我查看了它的代码,发现无法控制在控制器级别使用的查询生成器。
可以将整个 elastica_to_model_transformer
更改为自定义服务,但它仍然是在配置中静态定义的。也许使用一些肮脏的解决方案可能会采用这种方式,但我认为这不值得。
我决定不使用 FOSElasticaBundle 的这个功能。我遇到的主要问题是,当您使用 fos_elastica.index
而不是 fos_elastica.finder
或 elastica 存储库(为了获得简单的未转换结果 Elastica\Resultset
)时,没有 findPaginated
方法returns Pagerfanta
paginator 对象,这对我来说很有帮助。
幸运的是,虽然文档中没有提到它,但也可以通过这种方式创建 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 联系起来。因此,如果您在 ElasticSearch 中拥有所有需要的数据(当然如果它们是只读数据),您可以放弃从 Doctrine 获取数据。这使您可以优化应用程序性能,同时减少 SQL 查询的数量。
上面的代码可能包含某种服务,以防止在控制器中造成混乱。