如何使用Doctrine 2在Zend Framework 2中集成Elasticsearch

 zhuyiming69751 发布于 2022-12-28 19:01

我按照本教程将教程与Zend Framework 2集成.现在,一切正常,但我想将Elasticsearch集成到这个项目中.

我发现了很多关于Elasticsearch的文档,我下载了用于PHP的Elastica插件,但我不知道从哪里开始.

我搜索了教程以将Elasticsearch与Doctrine集成,但它们都是关于Symfony的.有人可以解释一下(以简单的方式)如何在Zend Framework 2中使用ElasticSearch,使用Doctrine 2作为ORM来索引和搜索我的对象吗?

1 个回答
  • Doctrine 2Elasticsearch之间没有直接关系.虽然Doctrine ORM的主要关注点是持续存在,更新和读取关系数据库上的数据,但elasticsearch主要关注索引和搜索数据.不要考虑"将弹性搜索与学说整合",而是考虑" 我如何在同一个应用程序中同时使用教义和弹性搜索".

    当你创建或更新数据库中的记录,你可能会想这样做更像是在数据的索引操作ElasticsearchSolr的,缓存或无效已经缓存在相同数据的版本的MemcachedRedis的等等.要做到这一点正确(或ZF2方式),你应该仔细设计一个服务层,它编排持久性操作和相关的后期处理,如弹性​​搜索索引,缓存,缓存失效,日志记录等.

    通过EventManager触发一些事件来完成其中一些操作将是一个合适的决定.

    注意:不要大量使用EventManager来完成简单而直接的任务,例如写日志行.事件不是免费的,特别是在ZF2中.(在ZF3中相当改进,但仍然没有免费).


    有问题,这里是使用Zend Framework 2同时使用ruflin/elastica的第三方库的方法:

    A.打开终端并输入

    $ cd /path/to/your/project
    $ php composer.phar selfupdate
    $ php composer.phar require ruflin/elastica:dev-master
    

    B.为elastica客户创建工厂Application\Service\ElasticaClientFactory.php

    <?php
    namespace Application\Service;
    
    use Zend\ServiceManager\FactoryInterface;
    use Zend\ServiceManager\ServiceLocatorInterface;
    
    class ElasticaClientFactory implements FactoryInterface
    {
        public function createService(ServiceLocatorInterface $sl)
        {
            $config = $sl->get('Config');
            $clientOptions = isset($config['elastica']) ? $config['elastica'] : array();
            $client = new \Elastica\Client($clientOptions);
    
            return $client;
        }
    }
    

    C.添加elastica配置并将新工厂类注册到您的服务定位器module.config.php:

    'elastica' => array(
        'servers' => array(
            array('host' => '127.0.0.1','port' => 9200),
            // You can add more servers when necessary
            // array('host' => '127.0.0.1','port' => 9200)
            ),
        ),
    
    service_manager' => array(
        'factories' => array(
            'elastica-client' => 'Application\Service\ElasticaClientFactory'
        ),
    )
    

    此时,在任何控制器(坏)或服务(好)中,您可以像这样获取elastica客户端实例:

    $elastica = $this->getServiceLocator()->get('elastica-client');
    

    奖励:使用服务初始化器和特征

    如果您的PHP版本≥5.4,您可以使用特征,同时在服务初始化程序的帮助下自动将Elastica客户端注入您的服务.

    D.创建一个名为的新接口Application\Service\ElasticaAwareInterface.php

    <?php
    namespace Application\Service;
    
    interface ElasticaAwareInterface
    {
        public function getElasticaClient();
        public function setElasticaClient(\Elastica\Client $client);
    }
    

    E.创建一个名为的新特征Application\Traits\ElasticaAwareTrait.php(注意路径.如果不存在,则创建Traits文件夹)

    <?php
    namespace Application\Traits;
    
    trait ElasticaAwareTrait
    {
        protected $client = null;
    
        public function getElasticaClient()
        {
            return $this->client;
        }
    
        public function setElasticaClient(\Elastica\Client $client)
        {
            $this->client = $client;
            return $this;
        }
    }
    

    F.创建一个名为的新初始化程序Application\Initializers\ElasticaInitializer.php(再次注意路径)

    <?php
    namespace Application\Initializers;
    
    use Zend\ServiceManager\InitializerInterface;
    use Zend\ServiceManager\ServiceLocatorInterface;
    use Application\Service\ElasticaAwareInterface;
    
    class ElasticaInitializer implements InitializerInterface
    {
        /**
         * Initializer for the elastica-aware domain services.
         * Properly creates a new elastica client and injects it into related service.
         */
        public function initialize($service, ServiceLocatorInterface $serviceManager)
        {
            /**
             * Beware: This if statement will be run for every service instance
             * we grab from $serviceManager because the nature of initializers.
             * This worth think about on it. With ZF3 this went further. 
             * We may load our services lazily using delegator factories.
             */ 
            if ($service instanceof ElasticaAwareInterface) {
                $service->setElasticaClient( $serviceManager->get('elastica-client') );
            }
        }
    }
    

    到现在为止还挺好.现在,我们可以将所有部分组合在一起.UserService比方说,我们有一个名为使用Doctrine实体管理器(或更好的UserRepository)的服务,也需要使用Elastica.

    G.将我们的服务注册到服务经理:

    service_manager' => array(
        'factories' => array(
            'elastica-client' => 'Application\Service\ElasticaClientFactory'
        ),
        'invokables' => array(
            'user-service' => 'Application\Service\UserService'
        )
    )
    

    最后,UserService签名:

    <?php
    namespace Application\Service;
    
    use Application\Service\ElasticaAwareInterface;
    
    class UserService implements ElasticaAwareInterface
    {
        // Here is our trait
        use \Application\Traits\ElasticaAwareTrait;
    
        public function fooMethod()
        {
            // Do some things with doctrine EM here..
    
            // And grab the elastica client easily anywhere in UserService
            $client = $this->getElasticaClient();
        }
    }
    

    2022-12-28 19:04 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有