ElasticSearchDSL: Order by relevence or other fields if set

314 Views Asked by At

hope you are well.

I am new to elastic search and using the ElasticSearchDSL plugin is amazing certainly when you have criterias where you can apply certain logic such as if something is set, include it, etc, etc.

I seem to hit a brick wall in terms of I want to be able to order by relevance as default BUT say give the option to order by date_closing, date_posted, etc (its a job search feature).

Unless I have missed some terminology on the ONGR website, anyone over come this type of scenario before ElasticSearchDSL?

I have below the current code (if required):

$termQueryForTitle = new ONGR\ElasticsearchDSL\Query\TermLevel\TermQuery('title', $keyword);
        $termQueryForDescription = new ONGR\ElasticsearchDSL\Query\TermLevel\TermQuery('description', $keyword);
        $termQueryForStatus = new ONGR\ElasticsearchDSL\Query\TermLevel\TermQuery('status', 1);
        $termQueryForDeleted = new ONGR\ElasticsearchDSL\Query\TermLevel\TermQuery('is_deleted', 0);
        $rangeQueryDateClosing = new ONGR\ElasticsearchDSL\Query\TermLevel\RangeQuery('date_closing', ['gte' => date('Y-m-d')]);
        $termsQuerySector = new ONGR\ElasticsearchDSL\Query\TermLevel\TermsQuery('job_sector_id', [implode('\', \'', array_filter($sector_id))]);
        $termsQuerySubject = new ONGR\ElasticsearchDSL\Query\TermLevel\TermsQuery('job_subject_id', [implode('\', \'', array_filter($subject_id))]);
        $termsQueryArea = new ONGR\ElasticsearchDSL\Query\TermLevel\TermsQuery('area_id', [implode('\', \'', array_filter($area_id))]);
        $termsQueryTown = new ONGR\ElasticsearchDSL\Query\TermLevel\TermsQuery('town_id', [implode('\', \'', array_filter($town_id))]);

        $bool = new ONGR\ElasticsearchDSL\Query\Compound\BoolQuery();
        //$bool->addParameter('minimum_should_match', 1);
        //$bool->addParameter('boost', 1);
        if($keyword != '')
        {
            $bool->add($termQueryForTitle, $bool::SHOULD);
            $bool->add($termQueryForDescription, $bool::SHOULD);
        }
        if(count($sector_id) > 0)
        {
            $bool->add($termsQuerySector, $bool::MUST);
        }
        if(count($subject_id) > 0)
        {
            $bool->add($termsQuerySubject, $bool::MUST);
        }
        if(count($area_id) > 0)
        {
            $bool->add($termsQueryArea, $bool::MUST);
        }
        if(count($town_id) > 0)
        {
            $bool->add($termsQueryTown, $bool::MUST);
        }
        $bool->add($rangeQueryDateClosing, $bool::MUST);
        $bool->add($termQueryForStatus, $bool::FILTER);
        $bool->add($termQueryForDeleted, $bool::FILTER);

        $DSL_search = new ONGR\ElasticsearchDSL\Search();
        $DSL_search->addQuery($bool);

        $query_params = $DSL_search->toArray();

        $data = $this->__elastic->Search_document('jobs', $query_params, $limit, $offset);
        //pprint_r($data);

TIA

1

There are 1 best solutions below

1
On

good to hear that you like ElasticSearchDSL. First advice, do not use BOOL query as a standalone. This query is designed to work as a helper inside the search object unless you really need it.

So instead try this approach. I added how to use sort as an example.

    $termQueryForTitle = new ONGR\ElasticsearchDSL\Query\TermLevel\TermQuery('title', $keyword);
    $termQueryForDescription = new ONGR\ElasticsearchDSL\Query\TermLevel\TermQuery('description', $keyword);
    $termQueryForStatus = new ONGR\ElasticsearchDSL\Query\TermLevel\TermQuery('status', 1);
    $termQueryForDeleted = new ONGR\ElasticsearchDSL\Query\TermLevel\TermQuery('is_deleted', 0);
    $rangeQueryDateClosing = new ONGR\ElasticsearchDSL\Query\TermLevel\RangeQuery('date_closing', ['gte' => date('Y-m-d')]);
    $termsQuerySector = new ONGR\ElasticsearchDSL\Query\TermLevel\TermsQuery('job_sector_id', [implode('\', \'', array_filter($sector_id))]);
    $termsQuerySubject = new ONGR\ElasticsearchDSL\Query\TermLevel\TermsQuery('job_subject_id', [implode('\', \'', array_filter($subject_id))]);
    $termsQueryArea = new ONGR\ElasticsearchDSL\Query\TermLevel\TermsQuery('area_id', [implode('\', \'', array_filter($area_id))]);
    $termsQueryTown = new ONGR\ElasticsearchDSL\Query\TermLevel\TermsQuery('town_id', [implode('\', \'', array_filter($town_id))]);


    $dslSearch = new ONGR\ElasticsearchDSL\Search();
    if($keyword != '') {
        $dslSearch->addQuery($termQueryForTitle, BoolQuery::SHOULD);
        $dslSearch->addQuery($termQueryForDescription, BoolQuery::SHOULD);
    }

    //.....
    //.....

    $sortField1 = new FieldSort('field_to_sort', FieldSort::ASC);
    $sortField2 = new FieldSort('second_field_to_sort', FieldSort::DESC);
    $dslSearch->addSort($sortField1);
    $dslSearch->addSort($sortField2);

    $query_params = $dslSearch->toArray();

    $data = $this->__elastic->Search_document('jobs', $query_params, $limit, $offset);
    //pprint_r($data);