Monday, 13 May 2019

Search multiple types at once with FOSElastica bundle

We have an existing class that extends FOS\ElasticaBundle\Repository, and it does a nice job of finding page objects, thanks to this yml:

        types:
            snapshot:
                mappings:
                    ignore_in_teaser_automatic:
                        type: boolean
                    publication_date_start:
                        type: date
                    publication_date_end:
                        type: date
                    page:
                        type: object
                        properties:
                        ...

... and this PHP:

    if ($limit === null) {
        $limit = 1000;
    }

    $script = new Script('floor(_score * 100)');
    $script->setLang('expression');

    // Recalculate score and adjust it to apply sorting by score
    $baseQuery = new Query\FunctionScore();
    $baseQuery->addScriptScoreFunction($script)
        ->setBoostMode(Query\FunctionScore::BOOST_MODE_REPLACE);


    $boolFilter = $this->getPublishBoolFilter();

    if (!empty($query)) {
        $matchQuery = new Query\MultiMatch();
        $matchQuery->setQuery($query)
            ->setFields([
                '_all',
                'page.title^20',
            ])
            ->setType(Query\MultiMatch::TYPE_MOST_FIELDS)
            ->setMinimumShouldMatch('45%')
        ;
        $boolFilter->addMust($matchQuery);
    }

    if (null !== $pageType) {
        $this->addPageTypeFilter($boolFilter, $pageType);
    }

    if ($filter instanceof Collection) {
        $this->addCollectionFilter($boolFilter, $filter);
    }

    if (is_numeric($filter)) {
        $this->addYearFilter($boolFilter, $filter);
    }

    $this->addSiteFilter($boolFilter, $site);

    $baseQuery->setQuery($boolFilter);

    $query = new Query();
    $query->setQuery($baseQuery);
    $query->setSort(
        array_merge(
            ['_score' => 'desc'],
            $order,
            self::getDefaultSortParams()
        )
    );


    return $this->find($query, $limit, $options);

... which gives me a nice array of plain-old-php Snapshot objects. Good.

Now I want to add matches from a second object type -- TrafficCompany. I add some yml ...

            traffic_company:
                properties:
                    name: ~
                    description: ~
                persistence:
                    driver: orm
                    model: AppBundle\Entity\TrafficCompany
                    provider: ~
                    finder: ~

... and I modify my PHP accordingly ...

            ...
            ->setType(Query\MultiMatch::TYPE_MOST_FIELDS)
            ->addType('traffic_company') //Does not seem to do anything useful. We still get exclusively Snapshot objects back.
            ->setMinimumShouldMatch('45%')
            ...

... but I now get an error.

Attempted to call an undefined method named "addType" of class "Elastica\Query\MultiMatch"

I've also tried a couple variations on this. Is there a simple way to add my new object type to the results?



from Search multiple types at once with FOSElastica bundle

No comments:

Post a Comment