我跟随this tutorial将该理论与Zend Framework 2集成在一起。现在,一切工作正常,但我想将Elasticsearch集成到该项目中。

我找到了很多有关Elasticsearch的文档,我下载了PHP的Elastica插件,但不知道从哪里开始。

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

最佳答案

教义2 Elasticsearch 之间没有直接关系。尽管Doctrine ORM的主要问题持续存在,更新和读取关系数据库上的数据,但elasticsearch主要致力于索引和搜索该数据。与其考虑“将 flex 搜索与理论整合在一起”,不如考虑“我如何在同一应用程序中同时使用理论和 flex 搜索”。

每当您在数据库中创建或更新记录时,您可能想要执行更多操作,例如在Elasticsearch或Solr上为该数据建立索引,在上将相同数据的已缓存版本缓存或使已缓存的版本无效,在Redis上将缓存在Redis上等等。正确地(或zf2方式),您应该仔细设计一个服务层,该服务层既要进行持久性操作,又要进行相关的后处理orchestrates,例如对Elasticsearch进行索引,缓存,缓存无效,日志记录等。

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



值得怀疑的是,这是使用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'
    ),
)

此时,在任何 Controller (坏)或服务(好)中,您都可以像下面这样抓取elastica客户实例:
$elastica = $this->getServiceLocator()->get('elastica-client');

奖励:使用服务初始化程序和特性

如果您的PHP版本≥5.4,则可以使用traits,同时借助service initializers将Elastica Client自动注入(inject)到您的服务中。

D. 创建一个名为Application\Service\ElasticaAwareInterface.php的新接口(interface)
<?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();
    }
}

关于php - 如何使用Doctrine 2将Elasticsearch集成到Zend Framework 2中,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/25242126/

10-09 04:26