Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

EZP-26368: As a developer I want to index custom data with Solr Search Engine #67

Merged
merged 12 commits into from Nov 24, 2016

Conversation

pspanja
Copy link
Contributor

@pspanja pspanja commented Sep 27, 2016

This PR resolves https://jira.ez.no/browse/EZP-26368

This is #42 continued.
As was discussed previously LocationTranslation mapper is here removed, to be proposed in a separate PR.

This implements document field mappers, aka indexing plugins feature.
Three types of base plugins are implemented:

  1. Content::mapFields(Content $content)
  2. ContentTranslation::mapFields(Content $content, $languageCode)
  3. Location::mapFields(Location $location)

For each of these an Aggregate plugin is implemented and used (6 places total):

  1. Content::mapFields(Content $content)
    1. Block - indexes fields on the block document level -- meaning to each Content and Location document in the block
    2. Content - indexes fields to each Content document
  2. ContentTranslation::mapFields(Content $content, $languageCode)
    1. BlockTranslation - indexes fields on the block level per translation
    2. ContentTranslation - indexes fields to Content document per translation
  3. Location::mapFields(Location $location)
    1. Location - indexes field to each Location document

The same, but starting from extension points (service tags):

  1. Block: ezpublish.search.solr.document_field_mapper.block
    • Accepts Content::mapFields(Content $content)
  2. Block translation: ezpublish.search.solr.document_field_mapper.block_translation
    • Accepts ContentTranslation::mapFields(Content $content, $languageCode)
  3. Content: ezpublish.search.solr.document_field_mapper.content
    • Accepts Content::mapFields(Content $content)
  4. Content translation: ezpublish.search.solr.document_field_mapper.content_translation
    • Accepts ContentTranslation::mapFields(Content $content, $languageCode)
  5. Location: ezpublish.search.solr.document_field_mapper.location
    • Accepts Location::mapFields(Location $location)

Concrete plugins are registered to Aggregate plugin in a container compiler pass, using service tags.
At the moment no concrete plugins are implemented, followup to this would be refactoring DocumentMapper to use only plugins to map fields. How that would look like can be seen here: pspanja#1
This is DocumentMapper fully refactored to use plugins: https://github.com/pspanja/ezplatform-solr-search-engine/blob/3a439bcf098b7e5a6c397204fc5849737cb1a60b/lib/DocumentMapper/NativeDocumentMapper.php

@pspanja pspanja changed the title Indexing plugins2 EZP-26368: As a developer I want to index custom data with Solr Search Engine Sep 27, 2016
@pspanja pspanja mentioned this pull request Sep 27, 2016
1 task
@pspanja
Copy link
Contributor Author

pspanja commented Sep 27, 2016

Ready for review, ping @andrerom @alongosz @bdunogier

Copy link
Member

@alongosz alongosz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1
(I would remove @version //autogentag// from all new files, beside that it looks good)

Copy link
Contributor

@andrerom andrerom left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1, however do you also have updated PR with the followup changes where inline logic is removed in favor of using this plugin system?

/**
* Base compiler pass for aggregate document field mappers.
*/
abstract class BaseDocumentFieldMapperPass implements CompilerPassInterface
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not a real review (I don't request the change), but we have similar compiler passes over the place. Shouldn't we try to have a common one that we can re-use in all of our packages ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess we could do that, it should probably be in ezpublish-kernel repo.

Copy link
Member

@bdunogier bdunogier left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There you go. I hope the review ain't too far off :)

/**
* Base class for document field mappers.
*/
abstract class FieldMapper
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not an interface rather than an abstract class ? i'd actually really suggest an interface. An abstract class would have a particular behaviour, while FieldMapper hints at a "role" (e.g. what it does).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually I think I'll just remove this, as it serves not purpose ATM. We can introduce it later on if need be.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed in a433031

*
* Content document field mapper maps Content to the search fields for Content document.
*/
abstract class Content extends FieldMapper
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above (interface vs. abstract class).

Also, I tend to avoid naming things "Content" or similar. We end up with an s'load of those. ContentFieldMapper is still short enough, is it not ?

(I won't be fanatic about it, just an improvement imho).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure about the benefit of the interface here, it's perfectly fine for abstract class not to have it's own implementation. Role would be more like FieldMapping.

Will rename when moving up.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Renamed (and moved up) in 30ffce1.

/**
* Aggregate implementation of Location document field mapper.
*/
class Aggregate extends LocationMapper
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it me or all of your Aggregate mappers have the same code ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's you :) They are mostly the same, but accept different mapper type.

{
$fields = [];

if ($this->locationTranslationFieldMapper->accept($location, $languageCode)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be shorter with a return early:

if ($this->locationTranslationFieldMapper->accept($location, $languageCode)) {
  return [];
}

return $this->locationTranslationFieldMapper->mapFields($location, $languageCode);

Copy link
Contributor Author

@pspanja pspanja Sep 29, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would, but I would not be able to process it at a glance :)
It's really a matter of style.

@@ -83,6 +117,12 @@ class NativeDocumentMapper implements DocumentMapper
/**
* Creates a new document mapper.
*
* @param \EzSystems\EzPlatformSolrSearchEngine\DocumentMapper\FieldMapper\Content $blockFieldMapper
Copy link
Member

@bdunogier bdunogier Sep 28, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is sparta

Jokes aside, could this be refactored to be a little slimer ? :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The only possibility I see is to move it up, on the same level as DocumentMapper.
I actually like that idea, it's the same approach I took in pspanja#4 with a number of other services.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moved up in 30ffce1

@pspanja
Copy link
Contributor Author

pspanja commented Sep 29, 2016

@alongosz

(I would remove @Version //autogentag// from all new files, beside that it looks good)

Removed in a2b3a89

@pspanja
Copy link
Contributor Author

pspanja commented Sep 29, 2016

@andrerom

do you also have updated PR with the followup changes where inline logic is removed in favor of using this plugin system?

Edited: Not updated yet, I wanted to do it in a followup.

@pspanja
Copy link
Contributor Author

pspanja commented Sep 29, 2016

I think I addressed all remarks.
I changed the structure a bit, moving FieldMapper up one level, so please take another look.

@andrerom
Copy link
Contributor

What do you think @bdunogier? From extensibility perspective do we hit a good spot here?

Copy link
Contributor

@andrerom andrerom left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1, but this implies master should be bumped to 1.2.x, so when this is merged, commit before should be branched of to 1.1 in case we need to do another 1.1 release.

@pspanja
Copy link
Contributor Author

pspanja commented Nov 4, 2016

There were no significant commits to master since the last change here, so with @bdunogier's approval I can move this forward.

@bdunogier
Copy link
Member

Is there an example that I can look at somewhere ? It would help a lot :)

@pspanja
Copy link
Contributor Author

pspanja commented Nov 4, 2016

The one linked in the description, should be virtually identical, aside from placement, removal of LocationTranslation mapper and removal of the common abstract class. The code you see there is basically what we'll be going for next with DocumentMapper refactoring to use plugins:

https://github.com/pspanja/ezplatform-solr-search-engine/blob/3a439bcf098b7e5a6c397204fc5849737cb1a60b/lib/DocumentMapper/NativeDocumentMapper.php

@bdunogier
Copy link
Member

bdunogier commented Nov 4, 2016

aside from placement, removal of LocationTranslation mapper and removal of the common abstract class

"lol" ;)

Thank you for the link, I'll look into it.

@pspanja
Copy link
Contributor Author

pspanja commented Nov 4, 2016

You're welcome. This is the code with consolidated field names and visitors, so basically removing unnecessary duplication even further:

https://github.com/pspanja/ezplatform-solr-search-engine/tree/3d7db66c36771fb26b5d70a94fe6fa7f496accd5/lib/DocumentMapper

Also do check the container configuration:

https://github.com/pspanja/ezplatform-solr-search-engine/blob/3d7db66c36771fb26b5d70a94fe6fa7f496accd5/lib/Resources/config/container/solr/document_field_mappers.yml

@bdunogier
Copy link
Member

Looks okay from an extensibility pov. It would be much easier to review this aspect with documentation about the said extensibility (I've found out that writing this doc together with the feature really helps).

*/
class ContentFieldMapperPass extends BaseFieldMapperPass
{
const AGGREGATE_MAPPER_SERVICE_ID = 'ezpublish.search.solr.field_mapper.content';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A bit late, so take that as an FYI, but you could have use one concrete class (FieldMapperPass), with the service id / service tag as arguments, and instantiate the Pass N times from the bundle, with the respective arguments. Less files, same result, easier to test.

@@ -0,0 +1,100 @@
# Document Field Mappers

As a website developer you will often find the need to index some additional data in the search
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

website developer => developer


As a website developer you will often find the need to index some additional data in the search
engine. The use cases for this are wide, for example the data could come from the external source
(for example from recommendation system), or from the internal source.
Copy link
Contributor

@andrerom andrerom Nov 23, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can be italic: (for example from recommendation system)

@pspanja pspanja merged commit c98bff0 into master Nov 24, 2016
@pspanja pspanja deleted the indexing_plugins2 branch November 24, 2016 09:44
@MarioBlazek
Copy link
Contributor

Excellent, thanks @pspanja .

@pspanja
Copy link
Contributor Author

pspanja commented Nov 30, 2016

@andrerom

+1, but this implies master should be bumped to 1.2.x, so when this is merged, commit before should be branched of to 1.1 in case we need to do another 1.1 release.

A little bit late with this, now created 1.1, alias bumped in #73

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
5 participants