4

I have a Symfony2 project, and I'm trying to implement a search feature using Elasticsearch.

My problem is, I need to index an entity with an optional self-relation. It means that my Item entity has a "parent" field, referencing another Item.

In order to make the search, I want to create filters on that "parent" field. Is my Item.parent is NULL ? for instance.

So, I am using the FosElasticaBundle.

Here is my mapping :

    types:
    Item:
        mappings:
            name:
            children:
                type: object
                _parent:
                    type: Item
            parent:
                type: object
        _routing:
            required: false
        _parent:
            type : Item
            identifier: id
            property : parent
        persistence:
            ...
            model_to_elastica_transformer:
                service: core.transformer.item

And the transformer does :

$document = new Document();

if (!is_null($item->getParent())) {
    $document->setParent($item->getParent()->getId());
} else {
     $document->setParent(null);
}

return $document;

And, the problem occurs when I try to create my index ( php app/console fos:elastica:populate )

This command returns the following ResponseException:

index: /traveler/Item caused RoutingMissingException[routing is required for [traveler]/[Item]/[null]] 

Do you have any idea why this isn't working ? And is this the good way to do it ?

Thanks,

TiPi
  • 330
  • 4
  • 19
  • Shouldn't the **$document->setParent($item->getParent()->getId());** receive an object **$document->setParent($item->getParent());** ? – costa Feb 09 '16 at 15:13
  • Thanks for your answer. Actually, the problem occured when the value was null (and I tried to set manually an id in that method, and it works). – TiPi Feb 09 '16 at 15:38
  • i think the ->getId() is not correct, change to `setParent($item->getParent())` – john Smith Feb 09 '16 at 16:40
  • 1
    @johnSmith as stated above, this is irrelevant, the problem occurs when there is no parent (equals 'null' value). the $item->getParent() equals null when there is no parent. – Aly Feb 10 '16 at 08:13

1 Answers1

1

Since my needs are pretty simple in this case, we managed to solve this problem.

Configuration

Instead of using the _parent field in config, I used a nested property.

Item:
    mappings:
        children:
            type: "nested"
            properties:
                name: ~
        parent:
            type: "object"

This is a tree, so children and parent properties are both Item. I needed to create requess with filter on the parent value (is null, is equals something...)

Request

So, I used the \Elasitca\Filter\Nested.

For instance, when I need to exclude some resultats based on children's user and language, I can do the following :

$nestedFilter  = new Nested();
$boolFilter    = new Bool();
$boolAndFilter = new BoolAnd();
$boolAndFilter
    ->setFilters(array(
        new Term(array("children.user.id" => $this->getClient()->getId())),
        new Term(array("children.other" => $language))
    ))
;

$nestedFilter
    ->setFilter($boolAndFilter)
    ->setPath('children')
;

$query = new Filtered(
    $query,
    new BoolNot($boolFilter->addMust($nestedFilter))
);

I think this solution has limitation (for multi-level parenting I assume), but for this need, it works.

TiPi
  • 330
  • 4
  • 19