私は Symphony 3 と FOSElasticaBundle 3.2 を使用していますが、やり方が少し異なります。他の回答で提供されたコードを確認した後、これは非常に役立ちましたが、デフォルトのリスナーを拡張しないことにしました。代わりに、独自のリスナーを追加しただけです。
複数の (1 対多の)投稿(3)を持つことができる複数の (多対多の)サブジェクト(2) を持つことができるいくつかのカテゴリ(1) があります。投稿は、Elasticsearch に保存されるエンティティであり、それぞれの件名と独自のカテゴリに関する情報が含まれています。
そのようです:
fos_elastica:
#...
indexes:
my_index:
#...
types:
post: # (3)
mappings:
field_one: ~
# ... Other fields
subject: # (2)
type: "object"
properties:
subject_field_one: ~
# ... Other fields
categories: # (1)
type: "nested"
properties:
category_field_one: ~
# ... Other fields
サービス定義 (app/config/services.yml)
services:
# ...
app.update_elastica_post.listener:
class: AppBundle\EventListener\UpdateElasticaPostListener
arguments: ['@service_container']
tags:
- { name: doctrine.event_listener, event: postUpdate }
そしてリスナー AppBundle\EventListener\UpdateElasticaPostListener.php
namespace AppBundle\EventListener;
use Doctrine\ORM\Event\LifecycleEventArgs;
use Symfony\Component\DependencyInjection\ContainerInterface;
use AppBundle\Entity\Category;
use AppBundle\Entity\Subject;
class UpdateElasticaPostListener
{
private $container;
private $objectPersisterPost;
public function __construct(ContainerInterface $container)
{
$this->container = $container;
$this->objectPersisterPost = null;
}
/**
* @param \Doctrine\ORM\Event\LifecycleEventArgs $eventArgs
*/
public function postUpdate(LifecycleEventArgs $eventArgs)
{
$this->checkAndUpdate($eventArgs);
}
protected function checkAndUpdate(LifecycleEventArgs $eventArgs)
{
$entity = $eventArgs->getEntity();
if ($entity instanceof Category) {
foreach ($entity->getSubjects() as $subject) {
$this->updateSubjectPosts($subject);
}
} elseif ($entity instanceof Subject) {
$this->updateSubjectPosts($entity);
}
}
protected function updateSubjectPosts(Subject $subject)
{
$this->initPostPersister();
foreach ($subject->getPosts() as $post) {
$this->objectPersisterPost->replaceOne($post);
}
}
protected function initPostPersister()
{
if (null === $this->objectPersisterPost) {
// fos_elastica.object_persister.<index_name>.<type_name>
$this->objectPersisterPost = $this->container->get('fos_elastica.object_persister.my_index.post');
}
}
}
以上です!remove イベントでは試していませんが、考えてみると、この解決策は最善の解決策ではないかもしれません...しかし、おそらく...
上記の@Ben Stintonと@maerckyに感謝します。
それが役立つことを願っています!(これは私の最初の回答なので、失敗しなかったことを願っています)