我有同样的问题。不过,我的安装(Symfony 2.5.4 和 FOSElastica 3.0.4)似乎与您的安装有很大不同。因此,使代码正常工作存在一些问题。我正在发布我的解决方案,因为它可能对其他开发人员有用。
Listener 不在 FOS\ElasticaBundle\Doctrine\ORM\ 中,而是在 FOS\ElasticaBundle\Doctrine 中。所以你必须使用那个。我还必须使用 Doctrine\Common\EventArgs 而不是 Doctrine\ORM\Event\LifecycleEventArgs,因为否则我自己的 postUpdate 方法与 BaseListener 中的方法不兼容。
在我的应用程序中,一个课程(研讨会)可以有很多会话,但在这个项目中,elastica 只会使用这些会话。该应用程序需要知道与课程会话相关的课程的一些详细信息。所以,这是我的代码:
在 config.yml 我的 elastica bundle 配置如下所示:
fos_elastica:
clients:
default: { host: localhost, port: 9200 }
indexes:
courses:
index_name: courses
types:
session:
mappings:
id: ~
name: ~
course:
type: "nested"
properties:
id: ~
name: ~
更进一步,还在 config.yml
services:
# some other services here
fos_elastica.listener.courses.course:
class: XXX\CourseBundle\EventListener\ElasticaCourseListener
arguments:
- @fos_elastica.object_persister.courses.course
- ['postPersist', 'postUpdate', 'preRemove']
- @fos_elastica.indexable
calls:
- [ setContainer, ['@service_container', @fos_elastica.object_persister.courses.session ] ]
tags:
- { name: 'doctrine.event_subscriber' }
我自己的监听器(XXX\CourseBundle\EventListener\ElasticaCourseListener)看起来像这样:
<?php
namespace XXX\CourseBundle\EventListener;
use Doctrine\Common\EventArgs;
use FOS\ElasticaBundle\Doctrine\Listener as BaseListener;
use FOS\ElasticaBundle\Persister\ObjectPersister;
use Symfony\Component\DependencyInjection\ContainerInterface;
use XXX\CourseBundle\Entity\Course;
class ElasticaCourseListener extends BaseListener
{
private $container;
private $objectPersisterSession;
public function setContainer(ContainerInterface $container, ObjectPersister $objectPersisterSession)
{
$this->container = $container;
$this->objectPersisterSession = $objectPersisterSession;
}
public function postUpdate(EventArgs $args)
{
$entity = $args->getEntity();
if ($entity instanceof Course) {
$this->scheduledForUpdate[] = $entity;
foreach ($entity->getSessions() as $session) {
$this->objectPersisterSession->replaceOne($session);
}
}
}
}
现在,当我更新课程时,它将作为 ElasticSearch 中的嵌套对象进行更新;-)