Custom Content subdocuments

This feature provides a way to index custom subdocuments under a Content document and a way to define criteria on them using Content search.

Note

This feature is available only for Solr search engine.

Note

It’s not possible to search for custom subdocuments directly. Instead, you can define subdocument criteria as a part of Content search, using SubdocumentQuery criterion.

Note

Relationship between Content and it’s subdocuments is not assumed. These can represent children under it’s main Location, Content relations of a specific ContentType or something else altogether.

Indexing custom subdocuments

In order to index custom subdocuments, you will need to implement a subdocument mapper plugin. Two extension points are provided, depending on how you want to index subdocuments:

1. Indexing custom subdocuments per Content

To index custom subdocuments per Content, implement a service extending Netgen\EzPlatformSearchExtra\Core\Search\Solr\SubdocumentMapper\ContentSubdocumentMapper class, defining two methods:

  • accept(Content $content): bool

    Here you will receive a Content that is being indexed as an instance of eZ\Publish\SPI\Persistence\Content. Using that object you have to decide whether you want to index custom subdocuments for it or not.

  • map(Content $content): Document

    Again you will receive an instance of eZ\Publish\SPI\Persistence\Content, which you can use to build and return an array of eZ\Publish\SPI\Search\Document instances. These represent custom subdocuments that will be indexed under the given Content.

Code example:

final class MyContentSubdocumentMapper extends ContentSubdocumentMapper
{
    public function accept(Content $content)
    {
        return $content->versionInfo->contentInfo->contentTypeId === 42;
    }

    public function mapDocuments(Content $content)
    {
        return [
            new Document([
                'id' => 'unique_id',
                'fields' => [
                    new Field(
                        'document_type',
                        'content_subdocument',
                        new FieldType\IdentifierField()
                    ),
                    new Field('price', 5 new FieldType\IntegerField()),
                ],
            ]),
        ];
    }
}

You also have to configure the mapper in the service container configuration, tagging it with netgen.search.solr.subdocument_mapper.content tag so that the system can find it.

my_content_subdocument_mapper:
    class: MyContentSubdocumentMapper
    tags:
        - {name: netgen.search.solr.subdocument_mapper.content}

2. Indexing custom subdocuments per Content translation

To index custom subdocuments per Content translation, implement a service extending Netgen\EzPlatformSearchExtra\Core\Search\Solr\SubdocumentMapper\ContentTranslationSubdocumentMapper class, defining two methods:

  • accept(Content $content, string $languageCode): bool

    Here you will receive a Content being indexed and a language that it’s being indexed in, as an instance of eZ\Publish\SPI\Persistence\Content and a language code string. Using these parameters you have to decide whether you want to index custom subdocuments for it or not.

  • map(Content $content, string $languageCode): Document

    Again you receive an instance of eZ\Publish\SPI\Persistence\Content and a language code string. You can use these to build and return an array of eZ\Publish\SPI\Search\Document instances, representing custom subdocuments that will be indexed under the given translation of a Content.

Code example:

final class MyContentTranslationSubdocumentMapper extends ContentSubdocumentMapper
{
    public function accept(Content $content, $languageCode)
    {
        $contentTypeId = $content->versionInfo->contentInfo->contentTypeId;

        return $contentTypeId === 42 && $languageCode === 'cro-HR';
    }

    public function mapDocuments(Content $content, $languageCode)
    {
        return [
            new Document([
                'id' => 'unique_subdocument_id',
                'fields' => [
                    new Field(
                        'document_type',
                        'content_translation_subdocument',
                        new FieldType\IdentifierField()
                    ),
                    new Field('price', 5 new FieldType\IntegerField()),
                ],
            ]),
        ];
    }
}

You also have to configure the mapper in the service container configuration, tagging it with netgen.search.solr.subdocument_mapper.content_translation tag so that the system can find it.

my_content_translation_subdocument_mapper:
    class: MyContentTranslationSubdocumentMapper
    tags:
        - {name: netgen.search.solr.subdocument_mapper.content_translation}

Note

It’s mandatory to define document_type field of IdentifierField type, in every Document you are returning. You must not use content or location here, since these are already used by the search engine.