eZ Platform Discussions

Sort by DatePublished and field publish_date




How to sort contents according to a “publish_date” field if it is entered and the publication date (that of the eZ system).

Content A : real publish date 10. No data in field “publish_date”
Content B : real publish date 20. Data in field “publish_date” : 05
Content C : real publish date 30. No data in field “publish_date”

I went B(05), A(10), C(30)

        $query = new LocationQuery();

        $query->filter = new Criterion\LogicalAnd([
            new Criterion\ContentTypeIdentifier(['article', 'breve']),
        $query->sortClauses = [
            new SortClause\DatePublished(Query::SORT_DESC),
            // new SortClause\Field('article', 'publish_date', Query::SORT_DESC), // Ne fonctionne pas pour 2 raisons. 1 il faut préciser le type. 2 on ne veux pas trier par date de publication réél puis par date de publication.

Does not work for 2 reasons. 1 the type must be specified. 2 you do not want to sort by actual publication date then by publication date.

Note: I use SOLR :slight_smile:

Merci pour votre aide.


Salut !

I have created a Document Field Mappers

namespace MyBundle\DocumentFieldMappers;

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

class PublishDateFieldMapper extends ContentFieldMapper
    protected $repository;

    public function __construct(Repository $repository) {
        $this->repository = $repository;

    public function accept(Content $content)
        return in_array($content->versionInfo->contentInfo->contentTypeId, [2/*Article*/, 51/*breve*/]);

    public function mapFields(Content $content)
        $v = $content->versionInfo->contentInfo->publicationDate; // int

        $c = $this->repository->getContentService()->loadContent($content->versionInfo->contentInfo->id);
        // Isn't it too overkill to load content here? 

        /** @var \eZ\Publish\Core\FieldType\DateAndTime\Value $f */
        $f = $c->getFieldValue('publish_date');
        if ($f && $f->value && $f->value->getTimestamp()) {
            $v = $f->value->getTimestamp();

        return [
            new Search\Field(
                new Search\FieldType\DateField()


        class: MyBundle\DocumentFieldMappers\PublishDateFieldMapper
            - '@ezpublish.api.repository'
            #- {name: ezpublish.search.solr.field_mapper.content} # Only content
            - {name: ezpublish.search.solr.field_mapper.block} # Content and Location :)

Now I just have to understand how to use it in my query.

        $query = new LocationQuery();
        $query->sortClauses = [ // TODO
            //new SortClause\DatePublished(Query::SORT_DESC),
            //new SortClause\Field('article', 'publish_date', Query::SORT_DESC), // Ne fonctionne pas pour 2 raisons. 1 il faut préciser le type. 2 on ne veux pas trier par date de publication réél puis par date de publication.


I changed field_mapper. I put block in place of content


In my Solr I have well the new indexed field.



But how do you use it in the sortClauses ?

new SortClause\Solr("publish_date_dt", Query::SORT_DESC) // DOES NOT EXISTE !



If I follow your explanations correctly, you want to sort on either the publication date field, if it is set, or on the content item’s publication date.

I kind of like your idea of customizing the publication date, since there is a criterion for that. It uses the field content_publication_date_dt, not publish_date_dt. Could you change your mapper so that it writes to that solr field ?

Then you should be able to use the DatePublished sort clause.


Hy @bertrand.dunogier,

It would probably work. But it would deprive me of the ability to filter on the real publication date…

In addition. I have other similar problems that cannot be solved in this way.
For example: I have several types of content with a numeric field. And I want to be able to sort these contents according to the value of this field.


But it would deprive me of the ability to filter on the real publication date…

Do you need to ? It seems to me that for those items, the real publication date is the one chosen by your mapper. But if you want it as a custom field, then I need to know more about the error you report when using new SortClause\Solr("publish_date_dt", Query::SORT_DESC). What do you mean by “does not exist” ?


I mean the class SortClause\Solr doesn’t exist.
This imaginary SortClause allows you to sort on a Solr field.
I have no idea how to make it real.


I mean the class SortClause\Solr doesn’t exist.

I didn’t pay attention to that part :slight_smile:

I’d say that you need to create a custom SortClause and a custom Solr SortClauseVisitor.

The SortClause is a simple value object, almost identical to eZ\Publish\API\Repository\Values\Content\Query\SortClause\DatePublished.

As for the SortClauseVisitor, you can start from EzSystems\EzPlatformSolrSearchEngine\Query\Common\SortClauseVisitor\DatePublished. It needs to be defined as a service, and tagged accordingly:

            - {name: ezpublish.search.solr.query.content.sort_clause_visitor}
            - {name: ezpublish.search.solr.query.location.sort_clause_visitor}

The visitor should of course use the custom field you add to the index.
I hope it helps.


Merci @bertrand.dunogier.

I think I’m almost there…


namespace MyBundle\SortClauseHandler;
use eZ\Publish\API\Repository\Values\Content\Query;
use eZ\Publish\API\Repository\Values\Content\Query\SortClause;
class CustomDatePublishedSortClause extends SortClause
    public function __construct($sortDirection = Query::SORT_ASC)
        parent::__construct('date_published', $sortDirection);


namespace Edb\PressePro3Bundle\SortClauseHandler;
use EzSystems\EzPlatformSolrSearchEngine\Query\SortClauseVisitor;
use eZ\Publish\API\Repository\Values\Content\Query\SortClause;
class CustomDatePublishedSortClauseVisitor extends SortClauseVisitor
    public function canVisit(SortClause $sortClause)
        return $sortClause instanceof CustomDatePublishedSortClause;

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


        class: MyBundle\SortClauseHandler\CustomDatePublishedSortClauseVisitor
            - {name: ezpublish.search.solr.query.content.sort_clause_visitor}
            - {name: ezpublish.search.solr.query.location.sort_clause_visitor}

In my controller :

        $query->sortClauses = [
            new CustomDatePublishedSortClause(Query::SORT_DESC),

But this has no impact on the sorting.

However, it was sent to SOLR.


    protected function search(array $parameters)
        $queryString = $this->generateQueryString($parameters);

/* LINE 448 */ dump($parameters, $queryString); die();
        // ...

Debug =>

Native.php on line 448: array:8 [
  "defType" => "edismax" 
  "q" => "{!lucene}*:*" 
  "fq" => "{!lucene}((document_type_id:"location") AND (meta_indexed_is_main_translation_b:"true") AND ((content_type_id_id:"2" OR content_type_id_id:"51" OR content_type_id_id:"52") AND (path_string_id:\/1\/2\/60\/126\/*) AND (content_section_id_id:"1" OR content_section_id_id:"3")))"
  "sort" => "publication_date_dt desc" 
  "start" => 0 
  "rows" => 0 
  "fl" => "*,score,[shard]" 
  "wt" => "json" 
Native.php on line 448:


And if I search directly in Solr, the results are well sorted.


Fixed a typo and it works :slight_smile:


        parent::__construct('publish_date', $sortDirection);


        return 'publish_date_dt' . $this->getDirection($sortClause);

In accordance with my Field Mapper :

       return [
            new Search\Field(
                new Search\FieldType\DateField()

Merci @bertrand.dunogier.


I’m happy that it worked, Remy :slight_smile:


Me to :wink:

I think this doc is not uptodate : https://doc.ezplatform.com/en/1.7/guide/search/#how-to-configure-your-own-criterion-and-sort-clause-handlers


Salut @bertrand.dunogier,

The solution I implemented works very well.
But it does not allow to sort the contents in the admin interface.
And it became a problem (2 weeks before the production start)
So I may have to implement the solution you recommended. That is, overwrite the indexed value in content_publication_date_dt

        return [
            // Erase the standard key
            new Search\Field(
                'content_publication_date', // => "content_publication_date_dt"
                new Search\FieldType\DateField()

But overwriting a value is apparently not done in the same way as adding a key.

Wrong HTTP status received from Solr: 400 on http://solr:8983/solr/collection1
ERROR: [doc=location66916langfrefr] multiple values encountered for non multiValued field content_publication_date_dt: [2019-03-15T13:48:00Z, 2019-03-15T13:48:36Z]",“code”:400}}

Merci pour ton aide.
Or the help of the community.