Are Types From The ICU-Plugin Supported Yet?

Hi,

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? :smiley: ).

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 :slight_smile:

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.

1 Like