Doctrine 2とElasticsearchの間に直接的な関係はありません。Doctrine ORM の主な関心事は、リレーショナル データベースでのデータの永続化、更新、および読み取りですが、elasticsearch は主にそのデータのインデックス作成と検索に焦点を当てています。「elasticsearch と doctrine の統合」について考える代わりに、「同じアプリケーションで doctrine と elasticsearch の両方を使用するにはどうすればよいか」について考えてください。
データベースでレコードを作成または更新するときはいつでも、ElasticsearchまたはSolrでそのデータのインデックスを作成したり、 MemcachedまたはRedisなどで既にキャッシュされた同じデータのバージョンをキャッシュまたは無効にしたりするなど、より多くの操作を実行する必要があります。それを適切に行うには (または zf2方法)、永続化操作と関連する後処理 (elasticsearch でのインデックス作成、キャッシュ、キャッシュの無効化、ログ記録など) の両方を調整するサービス レイヤーを慎重に設計する必要があります。
EventManagerを介していくつかのイベントを発生させることにより、これらの操作の一部を達成することは適切な決定です。
注: ログ行の書き込みなど、単純で単純なタスクに EventManager を多用しないでください。特にZF2では、イベントは無料ではありません。( ZF3 ではかなり改善されましたが、まだ無料ではありません)。
質問のために、 ruflin/elasticaであるサードパーティのライブラリを利用しながら Zend Framework 2 を使用する方法を次に示します。
A.端末を開いて入力します
$ cd /path/to/your/project
$ php composer.phar selfupdate
$ php composer.phar require ruflin/elastica:dev-master
B.エラスティカ クライアントのファクトリを作成する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.エラスティカ構成を追加し、新しいファクトリ クラスをサービス ロケータに登録します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 = $this->getServiceLocator()->get('elastica-client');
おまけ: サービス初期化子と特性の使用
PHP のバージョンが 5.4 以上の場合は、トレイトを使用しながら、サービスの初期化子を使用して Elastica Client をサービスに自動的に挿入できます。
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
(パスに注意してください。存在しない場合は特性フォルダーを作成します)
<?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();
}
}