Solr extensibility¶
Solr can be extended by adding several functionalities, such as document field mappers, custom search criteria, or custom sort clauses.
Document field mappers¶
You can use document field mappers to index additional data in the search engine.
The additional data can come from external sources (for example, the Personalization service), or from internal ones. An example of indexing internal data is indexing data through the Location hierarchy: from the parent Location to the child Location, or indexing child data on the parent Location. You can use this to find the content with full-text search, or to simplify a search in a complicated data model.
To do this effectively, you must understand how the data is indexed with the Solr search engine. Solr uses documents as a unit of data that is indexed. Documents are indexed per translation, as content blocks. A block is a nested document structure. When used in eZ Platform, a parent document represents content, and Locations are indexed as child documents of the Content item. To avoid duplication, full-text data is indexed on the Content document only. Knowing this, you can index additional data by the following:
- All block documents (meaning content and its Locations, all translations)
- All block documents per translation
- Content documents
- Content documents per translation
- Location documents
Additional data is indexed by implementing a document field mapper and registering it at one of the five extension points described above. You can create the field mapper class anywhere inside your bundle, as long as you register it as a Symfony service. There are three different field mappers. Each mapper implements two methods, by the same name, but accepting different arguments:
ContentFieldMapper
::accept(Content $content)
::mapFields(Content $content)
ContentTranslationFieldMapper
::accept(Content $content, $languageCode)
::mapFields(Content $content, $languageCode)
LocationFieldMapper
::accept(Location $content)
::mapFields(Location $content)
Mappers can be used on the extension points by registering them with the service container by using service tags, as follows:
- All block documents
ContentFieldMapper
ezpublish.search.solr.field_mapper.block
- All block documents per translation
ContentTranslationFieldMapper
ezpublish.search.solr.field_mapper.block_translation
- Content documents
ContentFieldMapper
ezpublish.search.solr.field_mapper.content
- Content documents per translation
ContentTranslationFieldMapper
ezpublish.search.solr.field_mapper.content_translation
- Location documents
LocationFieldMapper
ezpublish.search.solr.field_mapper.location
The following example shows how you can index data from the parent Location content, to make it available for full-text search on the child content. The example relies on a use case of indexing webinar data on the webinar events, which are children of the webinar. The field mapper could then look like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
|
You index full text data only on the content document, therefore, you would register the service like this:
1 2 3 4 5 6 7 |
|
Permission issues when using Repository API in document field mappers
Document field mappers are low-level and expect to be able to index all content
regardless of current user permissions.
If you use PHP API in your custom document field mappers, apply sudo()
,
or use the Persistence SPI layer as in the example above.
Custom Search Criteria¶
To provide support for a custom Search Criterion, do the following.
First, create an src/Query/Criterion/CameraManufacturerCriterion.php
file
that contains the Criterion class:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
|
Then, add an src/Query/Criterion/CameraManufacturerVisitor.php
file,
implement CriterionVisitor
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
|
Finally, register the visitor as a service.
Search Criteria can be valid for both Content and Location search.
To choose the search type, use either content
or location
in the tag:
1 2 3 4 5 |
|
Custom Sort Clause¶
To create a custom Sort Clause, do the following.
First, add an src/Query/SortClause/ScoreSortClause.php
file with the Sort Clause class:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|
Then, add an src/Query/SortClause/ScoreVisitor.php
file that implements SortClauseVisitor
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
|
The canVisit()
method checks whether the implementation can handle the requested Sort Clause.
The visit()
method contains the logic that translates Sort Clause information into data that is understandable by Solr.
The visit()
method takes the Sort Clause itself as an argument.
Finally, register the visitor as a service.
Sort Clauses can be valid for both Content and Location search.
To choose the search type, use either content
or location
in the tag:
1 2 3 4 5 |
|