Hello,
I have an existing ES index with its own predefined analyzers. I am trying to attach Hibernate Search to it but during the initial schema validation I get the following errors:
Code:
Caused by: org.hibernate.search.elasticsearch.schema.impl.ElasticsearchSchemaValidationException: HSEARCH400033: An Elasticsearch schema validation failed:
index 'entity.bravo_dev', mapping 'a.b.c.Entity', property 'text_body':
Invalid value for attribute 'analyzer'. Expected 'null', actual is 'custom_standard_analyzer'
index 'entity.bravo_dev', mapping 'a.b.c.Entity', property 'text_body_raw':
Invalid value for attribute 'index'. Expected 'ANALYZED', actual is 'NOT_ANALYZED'
The 'text_body' and 'text_body_raw' fields are added via a class bridge. In ES the 'text_body' is analyzed with an analyzer 'custom_standard_analyzer' defined in ES (and not in Hibernate). The 'text_body_raw' is not supposed to be analyzed.
My class bridge is as follows (simplified):
Code:
public class ComputedFieldsClassBridge implements Discriminator, MetadataProvidingFieldBridge {
public static final org.apache.lucene.document.FieldType TEXT_NOT_STORED_WITH_OFFSETS = new org.apache.lucene.document.FieldType();
public static final org.apache.lucene.document.FieldType STRING_NOT_STORED_NOT_ANALYZED = new org.apache.lucene.document.FieldType();
static {
TEXT_NOT_STORED_WITH_OFFSETS.setStored(false);
TEXT_NOT_STORED_WITH_OFFSETS.setTokenized(true);
TEXT_NOT_STORED_WITH_OFFSETS.setIndexOptions(IndexOptions.DOCS_AND_FREQS_AND_POSITIONS_AND_OFFSETS);
TEXT_NOT_STORED_WITH_OFFSETS.setOmitNorms(false);
TEXT_NOT_STORED_WITH_OFFSETS.freeze();
STRING_NOT_STORED_NOT_ANALYZED.setStored(false);
STRING_NOT_STORED_NOT_ANALYZED.setTokenized(false);
STRING_NOT_STORED_NOT_ANALYZED.setIndexOptions(IndexOptions.DOCS);
STRING_NOT_STORED_NOT_ANALYZED.setOmitNorms(true);
STRING_NOT_STORED_NOT_ANALYZED.freeze();
}
@Override
public void set(String name, Object value, Document document, LuceneOptions luceneOptions) {
//...
document.add(new Field("text_body", "<computed value>", TEXT_NOT_STORED_WITH_OFFSETS));
document.add(new Field("text_body_raw", "<computed value>", STRING_NOT_STORED_NOT_ANALYZED));
//...
}
@Override
public void configureFieldMetadata(String name, FieldMetadataBuilder builder) {
builder
.field("text_body", FieldType.STRING).sortable(false)
.field("text_body_raw", FieldType.STRING).sortable(false);
}
@Override
public String getAnalyzerDefinitionName(Object value, Object entity, String field) {
switch (field) {
case "text_body":
return "custom_standard_analyzer";
}
return null;
}
}
The entity class-level annotations for the bridge:
Code:
@AnalyzerDiscriminator(impl = ComputedFieldsClassBridge.class)
@ClassBridge(impl = ComputedFieldsClassBridge.class)
My questions are:
1. How can I specify the analyzer to be used for the 'text_body' (should be 'custom_standard_analyzer') to avoid the first error? The analyzer is defined in Elasticsearch, so I cannot use @AnalyzerDef.
2. How can I mark the 'text_body_raw' field as 'not analyzed' to avoid the second error?
Thank you in advance