we’re currently evaluating Hibernate-Search 6 as a replacement for our self-made elasticsearch-framework. As we have international customers we make use of the ICU-Plugin provided for Elasticsearch. This mentioned Plugin contains several nice features for Unicode-related operations.
The ICU-Plugin also adds new field types to the index - one of that is called icu_collation_keyword.
As far as I understood, your StringIndexFieldType maps to DataTypes.TEXT in case an analyzer is set. In case no analyzer is set, DataTypes.KEYWORD is used (which is resolved to “keyword”).
So what I wanted to ask:
Is there already some kind of ICU-support for Hibernate-Search?
Did I miss some package I need to add to the project in order to get these types (or even a @IcuCollationKeywordField-annotation? ).
PS:
I currently worked around that issue by creating a new implementation of StandardIndexFieldTypeOptionsStep for that ICU-type + created a custom ValueBinder which takes an instance of that implementation. Maybe you got some better ideas
You can take advantage of currently unsupported types in a property bridge by leveraging ElasticsearchExtension.get(). Something like this should work:
public class MyBinder implements PropertyBinder<MyAnnotation> {
@Override
public void bind(PropertyBindingContext context) {
context.getDependencies().useRootOnly();
IndexFieldType<String> type = context.getTypeFactory()
.extension( ElasticsearchExtension.get() )
.asNative( "{ ... your native JSON mapping ... }" )
.toIndexFieldType();
context.setBridge( new Bridge(
context.getIndexSchemaElement()
.field( context.getBridgedElement().getName(), type )
.toReference()
) );
}
private static class Bridge implements PropertyBridge {
private Gson gson = new Gson();
private final IndexFieldReference<String> field;
private Bridge(IndexFieldReference<String> field) {
this.field = field;
}
@Override
public void write(DocumentElement target, Object bridgedElement,
PropertyBridgeWriteContext context) {
// Make sure to provide well-formatted JSON, escaping quotes in particular
String json = gson.toJson( new JsonPrimitive( (String) bridgedElement ) );
target.addValue( field, json );
}
}
}
Then apply @MyAnnotation wherever you need this binding.
See here for more information about property bridges.
It is not possible to use the same technique in a value bridge (yet), because Hibernate Search needs to set the attributes defined in the @GenericField annotation, and that’s not possible when the mapping is defined as raw JSON. I created https://hibernate.atlassian.net/browse/HSEARCH-3717 to try and address this limitation.