简体   繁体   English

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

[英]How to integrate Elasticsearch in Zend Framework 2 using Doctrine 2

I followed this tutorial for integrating doctrine with Zend Framework 2. Now, all is working fine, but I would like to integrate Elasticsearch to this project. 我遵循了本教程 ,将理论与Zend Framework 2集成在一起。现在,一切正常,但是我想将Elasticsearch集成到该项目中。

I found a lot of documentation about Elasticsearch, I downloaded the Elastica plugin for PHP, but I don't know where to get started. 我找到了很多有关Elasticsearch的文档,我下载了PHP的Elastica插件,但是我不知道从哪里开始。

I searched tutorials to integrate Elasticsearch with Doctrine, but they're all about Symfony. 我搜索了将Elasticsearch与Doctrine集成的教程,但它们都是关于Symfony的。 Could someone please explain me (in a simple way) how to use ElasticSearch in Zend Framework 2, using Doctrine 2 as ORM to index and search through my objects? 有人可以(以一种简单的方式)向我解释一下如何在Zend Framework 2中使用ElasticSearch,将Doctrine 2作为ORM来索引和搜索我的对象吗?

There are no direct relation exists between Doctrine 2 and Elasticsearch . 教义2Elasticsearch之间不存在直接关系。 While primary concern of Doctrine ORM is persisting, updating and reading data on relational databases, elasticsearch mainly focuses on indexing and searching that data. 尽管Doctrine ORM的主要问题持续存在,更新和读取关系数据库上的数据,但是Elasticsearch主要致力于索引和搜索该数据。 Instead of thinking about "integrating elasticsearch with doctrine" , think about "how can i use both doctrine and elasticsearch in same application" . 与其考虑“将弹性搜索与理论整合在一起”不如考虑“如何在同一应用程序中同时使用理论和弹性搜索”

Whenever you create or update a record in database, you would probably want to do more operations like indexing that data on Elasticsearch or Solr , caching or invalidating already cached version of same data on Memcached or Redis etc.. To do that properly (or zf2 way), you should carefully design a service layer which orchestrates both persistency operations and related post-processes like indexing on elasticsearch, caching, cache invalidating, logging etc.. 每当您在数据库中创建或更新记录时,您可能都想做更多的操作,例如在ElasticsearchSolr上为该数据建立索引,在MemcachedRedis上缓存或使已缓存版本的相同数据无效。要正确执行此操作(或zf2方式),你应该仔细设计了一个服务层编排既持久性业务和相关后处理像elasticsearch,缓存,缓存无效,测井等索引..

Accomplishing some of these operations by firing some events via EventManager would be an appropriate decision. 通过EventManager触发一些事件来完成其中一些操作将是一个适当的决定。

Note: Don't utilize EventManager heavily for simple & straightforward tasks such as writing a log line. 注意:不要将EventManager大量用于简单明了的任务,例如编写日志行。 Events are not free, especially in ZF2. 活动不是免费的,尤其是在ZF2中。 ( Quite improved in ZF3, but still not free ). 在ZF3中有很大的改进,但仍然不是免费的 )。


For question, here is the way to go with Zend Framework 2 while utilizing a 3rd party library which is ruflin/elastica : 有疑问的是,这是使用Zend Framework 2并同时使用ruflin / elastica的3rd party库的方法:

A. Open your terminal and type A.打开您的终端并输入

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

B. Create a factory for elastica client Application\\Service\\ElasticaClientFactory.php B.Application\\Service\\ElasticaClientFactory.php客户端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. Add elastica configuration and register new factory class to service locator in your module.config.php : 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'
    ),
)

At this point, in any controller (bad) or service (good) you can grab the elastica client instance like this: 此时,在任何控制器(坏)或服务(好)中,您都可以像下面这样抓取elastica客户实例:

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

Bonus: Using Service Initializers and Traits 奖励:使用服务初始化程序和特性

If your PHP version is ≥ 5.4 you can use traits while automatically injecting the Elastica Client into your services with the help of service initializers . 如果您的PHP版本≥5.4,则可以使用特征,同时借助服务初始化程序将Elastica Client自动注入服务中

D. Create a new interface named Application\\Service\\ElasticaAwareInterface.php D.创建一个名为Application\\Service\\ElasticaAwareInterface.php的新接口

<?php
namespace Application\Service;

interface ElasticaAwareInterface
{
    public function getElasticaClient();
    public function setElasticaClient(\Elastica\Client $client);
}

E. Create a new trait named Application\\Traits\\ElasticaAwareTrait.php (Notice the path. Create the Traits folders if doesn't exists) 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. Create a new initializer named Application\\Initializers\\ElasticaInitializer.php (Notice the path, again) F.创建一个名为Application\\Initializers\\ElasticaInitializer.php的新初始化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') );
        }
    }
}

So far so good. 到现在为止还挺好。 Now, we can put together all parts. 现在,我们可以将所有部分放在一起。 Say, we have a service named UserService which uses a Doctrine entity manger (or UserRepository better), also needs to use Elastica . 假设我们有一个名为UserService的服务,该服务使用Doctrine实体管理器(或更好的UserRepository),还需要使用Elastica

G. Register our service to service manager: G.向服务经理注册我们的服务:

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

Finally, the UserService signature: 最后, 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();
    }
}

There are some (still under heavy development) modules out there that combine Doctrine2 and ElasticSearch. 有一些(仍在开发中)模块结合了Doctrine2和ElasticSearch。 For example check out this module called OcraElasticSearch from the Doctrine2+ZF2 Master @Ocramius himself :) 例如,从Doctrine2 + ZF2 Master @Ocramius本人中检查OcraElasticSearchOcraElasticSearch模块 :)

Otherwise it seems that Symfony2 is a step ahead when it comes to integrating Doctrine and ElasticSearch. 否则,在集成Doctrine和ElasticSearch方面,Symfony2似乎领先一步。

I bet within one or two months you should be able to find more alternatives on GitHub. 我敢打赌,在一两个月之内,您应该可以在GitHub上找到更多替代方案。

Since we need similar functionality soon I might discover more later. 由于我们很快需要类似的功能,因此我可能会在以后发现更多功能。 If I do I will update my post. 如果我愿意,我会更新我的帖子。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM