Ben*_*ton 13 doctrine symfony symfony-2.4 foselasticabundle
我在我的项目中使用FOSElasticaBundle和Doctrine,我的代码用于使用Doctrine生命周期事件进行选择性索引更新.我遇到的问题是我是否单独更新相关实体.
例如,一个人可能通过多种关系与公司相关.如果我直接通过公司实体更新公司名称,那么与公司相关的人员的索引将过时,并且仍与公司的旧名称相关.
关于如何处理这个我有点迷失,有人有什么建议吗?我是否必须依赖计划的索引更新并同时处理不准确的索引数据,或者我是否可以调用与已更新的实体相关的实体的更新.
我依靠JMSSerializer组来建立映射.我很欣赏这可能不是长期做事的最佳方式.
小智 11
我遇到了同样的问题.看来我的安装(Symfony 2.5.4和FOSElastica 3.0.4)与你的安装有很大不同.因此,使代码工作存在一些问题.我正在发布我的解决方案,因为它可能对其他开发人员有用.
监听器不在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: ~
Run Code Online (Sandbox Code Playgroud)
再进一步,仍然在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' }
Run Code Online (Sandbox Code Playgroud)
我自己的监听器(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);
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
现在,当我更新课程时,它将作为ElasticSearch中的嵌套对象进行更新;-)
我想我已经在此页面上找到了解决方案https://groups.google.com/forum/#!topic/elastica-php-client/WTONX-zBTI4 谢谢 Cassiano
基本上,您需要扩展 FOS\ElasticaBundle\Doctrine\ORM\Listener,以便您可以查找相关实体,然后也更新它们的索引。
class CompanyListener extends BaseListener
{
/** @var \Symfony\Component\DependencyInjection\ContainerInterface */
private $container;
public function setContainer(\Symfony\Component\DependencyInjection\ContainerInterface $container) {
$this->container = $container;
}
protected function initialiseJob() {
$this->objectPersisterJob = $this->container->get('fos_elastica.object_persister.application.job');
$this->em = $this->container->get('doctrine')->getEntityManager(); //maybe move this to postUpdate function so it can be used for all
}
/**
* @param \Doctrine\ORM\Event\LifecycleEventArgs $eventArgs
*/
public function postUpdate(LifecycleEventArgs $eventArgs)
{
/** @var $entity Story */
$entity = $eventArgs->getEntity();
if ($entity instanceof $this->objectClass) {
if ($this->isObjectIndexable($entity)) {
$this->objectPersister->replaceOne($entity);
$this->initialiseJob();
foreach ($entity->getJobOpenings() as $job) {
$this->objectPersisterJob->replaceOne($job);
}
} else {
$this->scheduleForRemoval($entity, $eventArgs->getEntityManager());
$this->removeIfScheduled($entity);
}
}
}
public function preRemove(\Doctrine\Common\EventArgs $eventArgs)
{
$entity = $eventArgs->getEntity();
if ($entity instanceof $this->objectClass) {
$this->scheduleForDeletion($entity);
$this->initialiseJob();
foreach ($entity->getJobOpenings() as $job) {
$this->objectPersisterJob->replaceOne($job);
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
以及您的服务定义如下
fos_elastica.listener.application.company:
class: 'xxx\RMSBundle\EventListener\CompanyListener'
arguments:
- '@fos_elastica.object_persister.application.company'
- 'xxx\RMSBundle\Entity\Company'
- ['postPersist', 'postUpdate', 'postRemove', 'preRemove']
- id
calls:
- [ setContainer, [ '@service_container' ] ]
tags:
- { name: 'doctrine.event_subscriber' }
Run Code Online (Sandbox Code Playgroud)
这将更新两者的索引:-)
| 归档时间: |
|
| 查看次数: |
7724 次 |
| 最近记录: |