【问题标题】:FOSElasticaBundle: Is it possible to change "query_builder_method" in controller?FOSElasticaBundle:是否可以在控制器中更改“query_builder_method”?
【发布时间】:2016-08-31 13:29:50
【问题描述】:

根据FOSElasticaBundle documentation,可以将应用程序配置为使用自定义查询构建器方法,如下所示:

user:
   persistence:
       elastica_to_model_transformer:
           query_builder_method: createSearchQueryBuilder

但是是否可以选择QB方法live,例如在控制器操作中?

我希望能够在将 Elastica 结果转换为 Doctrine 实体时控制从数据库中获取的内容。例如。有时我想对某些关系进行 Eager fetch,但默认情况下不能这样做。

【问题讨论】:

    标签: php symfony elastica foselasticabundle


    【解决方案1】:

    由于 FOSElasticaBundle 文档不是很精确,我查看了它的代码,发现无法控制在控制器级别使用什么查询构建器。

    可以将整个elastica_to_model_transformer 更改为自定义服务,但它仍然是在配置中静态定义的。也许有一些肮脏的解决方案可能会走这条路,但我认为这不值得。

    我决定不使用 FOSElasticaBundle 的这个功能。我遇到的主要问题是,当您使用fos_elastica.index 而不是fos_elastica.finder 或elastica 存储库时(为了获得简单的未转换结果Elastica\Resultset),没有findPaginated 方法返回Pagerfanta 分页器对象,对我来说非常有帮助。

    幸运的是,虽然文档中没有提到它也可以通过这种方式创建 Pagerfanta,但需要更多手动操作。

    这是一个代码sn-p:

    //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 查询量。

    上面的代码可能会被某种服务包裹,以防止控制器混乱。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-11-22
      • 2015-05-07
      • 2016-06-20
      • 2017-12-14
      • 2020-05-27
      相关资源
      最近更新 更多