Search code examples
symfonyelasticsearchfoselasticabundle

Define elasticsearch field type using FOSelastica TransformEvent


I'm working on a existing Symfony project that uses FOS Elastica Bundle, and especially the TransformEvent.

elastica.yml

    types:
         object:        
             mappings: ~
             persistence:
                identifier: id
                driver: orm
                model: Bundle\Entity\Object
                listener: ~
                provider: ~
                finder: ~

listener

public function addCustomProperties(TransformEvent $event)
{   
    $document = $event->getDocument();
    $object = $event->getObject();

    /* elements */
    $elementsList = $object->getElements();
    $elements = [];
    foreach($elementsList as $element)
    {
        $elements[] = array(
            'id' => $element->getId(),
            'value' => $element->getValue(),
            'type' => $element->getType()
    }

   $document->set( 'elements', $elements );

}

public static function getSubscribedEvents() {
    return array(
            TransformEvent::POST_TRANSFORM => 'addCustomProperties'
    );
}

I would like to index 'elements' as nested, like it is explained here, but i can't figure out how to do it. I've tried to change the mapping in elastica.yml without success. For example, this returns error :

types:
     object:        
         mappings: 
            elements:
               type: nested
         etc.

=> Object of class Bundle\Entity\Element could not be converted to a string

So, I was wondering if it could be possible to define the 'elements' type as 'nested' during the $document->set( 'elements', $elements ); ?

Thanks for any kind of help !


Solution

  • The field "elements" (that I wanted to set as "nested") did not exists in the "model" (Bundle\Entity\Object). However, it had to be so since I use this model for the mapping.

    TransformEvent allows to add custom fields to the mapping, but in that case their type is set automatically.

    I just had to put a new property inside the model (without annotations because I don't want that property to be in the database)

    Bundle\Entity \Object

    /** some properties **/ 
    
    private $elements;
    
    /**
    * Constructor stuff
    **/
    
    /**
    * Set elements
    */
    public function getElements()
    {
        return $this->elements;
    }
    

    elastica.yml

    types:
         object:        
             mappings:
                elements:
                    type: nested
             # etc.
    

    I don't know if this is a proper way for the use of the TransformEvent, but it did works for me.