Ibexa DXP Discussions

Community discussion forum for developers working with Ibexa DXP

Sort by field on multiple content type

Salutations,

I need all the items back, A’s son.
Who is assigned main_menu greater than 0.
Sorted by main_menu descending

A can contain any kind of objects.
All these objects do not necessarily have the main_menu attribute. (It does not exist in their ContentType)
I don’t want to list ContentType that have this attribute.

        $query = new LocationQuery();
        $query->filter = new Query\Criterion\LogicalAnd([
            new Query\Criterion\ParentLocationId($location->id),
            new Query\Criterion\Field('main_menu', '>', 0),
        ]);
        $query->sortClauses = [
            new Query\SortClause\Field(/* ? */ , 'main_menu', Query::SORT_ASC), // TODO
        ];
        $searchResut = $this->getRepository()->getSearchService()->findLocations($query);

The problem is that Query\SortClause\Field is waiting for a $typeIdentifier first parameter and I don’t have one…

In eZ4 we used to go through sorl to do that.
Something like:

sort_by, hash( 'attr_main_menu_i', desc))})

How can I do the same with eZPlatform 2.2?

Did anybody get to the solution of this?
Because I need the same thing.

As I know you need to use Solr and a custom ContentFieldMapper to create a new field in Solr with your value with same name for each contenttype.
And use new Query\SortClause\CustomField("custom_field_s", Query::SORT_ASC) provided by Netgen\EzPlatformSearchExtra bundle

Read: https://doc.ezplatform.com/en/2.5/guide/solr/#extending-the-solr-search-engine-bundle

hi,

Sorry I didn’t share my solution here at the time.

First : I used a ContentFieldMapper to index an extra field : ‘main_menu’ => “main_menu_i”

namespace My\DocumentFieldMappers;

use eZ\Publish\API\Repository\Repository;
use EzSystems\EzPlatformSolrSearchEngine\FieldMapper\ContentFieldMapper;
use eZ\Publish\SPI\Persistence\Content;
use eZ\Publish\SPI\Search;

class MainMenuFieldMapper extends ContentFieldMapper
{
    public function __construct(Repository $repository) {
        $this->repository = $repository;
    }

    public function accept(Content $content)
    {
        $ct = $this->repository->getContentTypeService()->loadContentType($content->versionInfo->contentInfo->contentTypeId);
        return !!$ct->getFieldDefinition('main_menu');
    }

    public function mapFields(Content $content)
    {
        $c = $this->repository->getContentService()->loadContent($content->versionInfo->contentInfo->id);
        /** @var \eZ\Publish\Core\FieldType\Integer\Value $f */
        $f = $c->getFieldValue('main_menu');
        if (!$f) {
            return [];
        }
        return [
            new Search\Field(
                'main_menu', // => "main_menu_i"
                $f->value,
                new Search\FieldType\IntegerField()
            ),
        ];
    }
}

Next I create a custom SolrSortClause

namespace My\SortClauseHandler;

use eZ\Publish\API\Repository\Values\Content\Query;
use eZ\Publish\API\Repository\Values\Content\Query\SortClause;

class MainMenuSortClause extends SortClause
{
    public function __construct($sortDirection = Query::SORT_ASC)
    {
        parent::__construct('main_menu', $sortDirection);
    }
}

And a SortClauseVisitor

namespace My\SortClauseHandler;

use EzSystems\EzPlatformSolrSearchEngine\Query\SortClauseVisitor;
use eZ\Publish\API\Repository\Values\Content\Query\SortClause;

class MainMenuSortClauseVisitor extends SortClauseVisitor
{
    public function canVisit(SortClause $sortClause)
    {
        return $sortClause instanceof MainMenuSortClause;
    }

    public function visit(SortClause $sortClause)
    {
        return 'main_menu_i' . $this->getDirection($sortClause);
    }
}

Services configuration :

my.document_field_mappers.main_menu:
    class: My\DocumentFieldMappers\MainMenuFieldMapper
    arguments:
        - '@ezpublish.api.repository'
    tags:
        - {name: ezpublish.search.solr.field_mapper.block}

my.solr.query.location.sort_clause_visitor.main_menu:
    class: My\SortClauseHandler\MainMenuSortClauseVisitor
    tags:
        - {name: ezpublish.search.solr.query.content.sort_clause_visitor}
        - {name: ezpublish.search.solr.query.location.sort_clause_visitor}

my.solr.query.location.sort_clause_visitor.solr_sort_clause:
    class: My\SortClauseHandler\SolrSortClauseVisitor
    tags:
        - {name: ezpublish.search.solr.query.content.sort_clause_visitor}
        - {name: ezpublish.search.solr.query.location.sort_clause_visitor}

Finaly :

$query->sortClauses = [
        new MainMenuSortClause(Query::SORT_DESC),
    ];

@ajakov
At the time it was in eZ 2.2

As @stevecohenfr said now it’s good to use Netgen\EzPlatformSearchExtra bundle