We're updating the issue view to help you get more done. 

Replace the searchable/sortable/projectable flags for fields with a single array of feature flags

Description

Right now, we enable features on fields like this:

1 2 3 4 5 6 7 8 @GenericField // Default features only, i.e. searchable private String myField1; @GenericField(sortable = Sortable.YES) // Searchable and sortable private String myField2; @GenericField(searchable = Searchable.NO, sortable = Sortable.YES) // Sortable only private String myField3;

There are a few problems with this syntax:

  1. It's not extensible. If we were to add an aggregation features to the Elasticsearch backend only, users would not be able to enable that feature directly from their annotation mapping, because there would be no generic way to do that.

  2. It's prone to errors... when creating a field specifically for sorts in particular, it is very likely that users will just forget about disabling "searchable", and will thus end up with an unnecessary index on that sort field.

What if we were to select the enabled features for a field by providing an array of enabled features, instead?

1 2 3 4 5 6 7 8 9 10 11 @GenericField // Default features only, i.e. searchable private String myField1; @GenericField(features = FieldFeatures.SORT) // Sortable only private String myField2; @GenericField(features = {FieldFeatures.PREDICATE, FieldFeatures.SORT}) // Searchable and sortable private String myField3; @GenericField(features = {FieldFeatures.PREDICATE, ElasticsearchFieldFeatures.AGGREGATION}) // Sortable and aggregable private String myField3;

Pros:

  • Features can now easily be extended.

  • Enabled features are now clearer: when you enable one explicitly, it's clear that other features need to be enabled explicitly too.

  • The naming of features can be more direct: no need for a "searchable" keyword, we can just call the feature "predicate".

  • It would be very easy for custom bridge implementors to reproduce the same syntax in their own bridge annotations. With one attribute for each feature, it was not very practical.

  • This syntax has a lot of potential for evolution. We might not want to allow everything below, but the point is we can:

    • We can consider allowing users to enable "low-level" features through this means too: LowLevelFeatures.DOC_VALUES, LowLevelFeatures.TERM_VECTORS, LowLevelFeatures.TERM_VECTORS_WITH_POSITIONS, ...

    • We can consider allowing users to declare named "feature groups", then allowing them to provide the name of a feature group instead of a list features directly.

Cons:

  • The name "feature" may not be the best; there's a concept of "feature" in Lucene which relates to pre-computed queries, if I remember correctly. We'd have to check that first, to be sure we're not introducing confusing terminology.

  • Extended features are limited: they are boolean flags (ESFeatures.AGGREGATION) or enums at most (ESFeatures.AGGREGATION_DISCRETE, ESFeatures.AGGREGATION_RANGE), but cannot easily support numeric parameters for example.

  • Annotations being what they are, the only suitable type for constants passed to the "features" attribute would be String. Which quite bad when it comes to guiding users to the list of available values. We could mitigate the issue by linking to the appropriate constant classes in the javadoc.

Environment

None

Status

Assignee

Unassigned

Reporter

Yoann Rodière

Labels

None

Suitable for new contributors

None

Pull Request

None

Feedback Requested

None

Fix versions

Priority

Major