Symfony2 FOSElasticaBundle update index for all entities related to the entity updated

前端 未结 7 1449
無奈伤痛
無奈伤痛 2020-12-30 06:07

I\'m using FOSElasticaBundle and Doctrine in my project, and my code works for the selective index update using the Doctrine lifecycle events. The issue I come up against is

7条回答
  •  被撕碎了的回忆
    2020-12-30 06:22

    I've had the same problem. It seems my installation (Symfony 2.5.4 and FOSElastica 3.0.4) differs quite a bit from yours though. Therefore, there were some problems to get the code working. I'm posting my solution, because it may be useful for other developers out there.

    The Listener isn't in FOS\ElasticaBundle\Doctrine\ORM\, but in FOS\ElasticaBundle\Doctrine. So you'll have to use that one. Also I had to use Doctrine\Common\EventArgs instead of Doctrine\ORM\Event\LifecycleEventArgs, 'cause otherwise my own postUpdate-method wasn't compatible with the one in the BaseListener.

    In my app, a course (seminar) can have a lot of sessions, but in this project, elastica will only be using those sessions. The app needs to know some details of the course that is related to the session of course. So, here's my code:

    In config.yml my elastica bundle config looks like this:

    fos_elastica:
        clients:
            default: { host: localhost, port: 9200 }
        indexes:
            courses:
                index_name: courses
                types:
                    session:
                        mappings:
                            id: ~
                            name: ~
                            course:
                                type: "nested"
                                properties:
                                    id: ~
                                    name: ~
    

    A little further, still in 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' }
    

    My own listener (XXX\CourseBundle\EventListener\ElasticaCourseListener) then looks like 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);
                }
            }
        }
    }
    

    Now, when I update a course, it will be updated as a nested object in ElasticSearch ;-)

提交回复
热议问题