Replace the searchable/sortable/projectable flags for fields with a single array of feature flags
Right now, we enable features on fields like this:
There are a few problems with this syntax:
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.
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?
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.
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. => Checked, it's true. "features" in the Lucene world are fields containing a pre-computed score, such as a pagerank.
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.
Solution for the confusing "feature" name
Alternative names: characteristic (a bit long), property (confusing), function (confusing), trait, capability, faculty, functionality.
Trait seems nice: