Search code examples
javahibernateelasticsearchhibernate-searchhibernate-search-6

Hibernate Search migration from 5.11.9 to 6.0.6 - analyzer not being applied


I'm having some issues in the migration process to the newer version of Hibernate Search, mainly related to dynamic fields and the associated analyzer not being applied.

First, i'm building the analyzers:

private void buildLocalizedAnalyzer(ElasticsearchAnalysisConfigurationContext builder) {
    SupportedLanguage.stream().forEach(
            supportedLanguage ->
            {
                builder.analyzer(supportedLanguage.getDescription() + "Analyzer").custom()
                        .tokenizer(STANDARD)
                        .tokenFilters(LOWERCASE, EDGE_NGRAM_3,
                                supportedLanguage.getDescription() + "Stemmer",
                                supportedLanguage.getDescription() + "Stop"
                        );

                builder.tokenFilter(supportedLanguage.getDescription() + "Stemmer")
                        .type("stemmer").param("language", supportedLanguage.getDescription());

                builder.tokenFilter(supportedLanguage.getDescription() + "Stop")
                        .type("stop").param("stopwords", "_" + supportedLanguage.getDescription() + "_");
            }
    );

}

And then, using a property binder and a bridge, i'm indexing the required fields:

@Override
public void bind(PropertyBindingContext context) {
    context.dependencies().useRootOnly();

    var rootField = context.indexSchemaElement()
            .objectField(context.bridgedElement().name());

    SupportedLanguage.stream().forEach(
            supportedLanguage -> context
                    .indexSchemaElement()
                    .fieldTemplate("localized_analyzer_" + supportedLanguage.name().toLowerCase(), f -> f
                            .asString()
                            .analyzer(supportedLanguage.getDescription() + "Analyzer"))
                    .matchingPathGlob("properties.search_" + supportedLanguage.name().toLowerCase() + "_*"));

     context.bridge(List.class, new PropertyValueBinder.Bridge(rootField.toReference()));
}

In the property bridge:

private void indexEnumPropertiesForLocalizedSearch(DocumentElement target,
                                                   PropertyValueEnum propertyValue,
                                                   EnumValue enumValue) {
    var fieldName = PREFIX_SEARCH + DEFAULT + DELIMITER + propertyValue.getProperty().getCode();
    var indexedValue = ((EnumValueString) enumValue).getValue();

    target.addValue(fieldName, indexedValue);

    enumValue.getTranslations().forEach((language, translation) -> {
        var fieldNameTranslated = PREFIX_SEARCH + language.getCode() + DELIMITER + propertyValue.getProperty().getCode();
        var indexedValueTranslated = translation.getValue();

        target.addValue(fieldNameTranslated, indexedValueTranslated);
    });
}

But when i'm retrieving the termvectors, no analyzer has been applied and the search doesn't work:

_termvectors/8?fields=properties.search_en_category

 {
        "_index": "product-000001",
        "_type": "_doc",
        "_id": "8",
        "_version": 1,
        "found": true,
        "took": 0,
        "term_vectors": {
            "properties.search_en_category": {
                "field_statistics": {
                    "sum_doc_freq": 4,
                    "doc_count": 4,
                    "sum_ttf": 4
                },
                "terms": {
                    "Category three": {
                        "term_freq": 1,
                        "tokens": [
                            {
                                "position": 0,
                                "start_offset": 0,
                                "end_offset": 14
                            }
                        ]
                    }
                }
            }
        }
    }

Am i missing something in the configuration/indexing process?

Thanks in advance


Solution

  • Did you make sure to drop and re-create your index before testing? The field templates are part of the schema, so you need to create the schema before they are effective. See https://docs.jboss.org/hibernate/stable/search/reference/en-US/html_single/#mapper-orm-schema-management

    If that's not the problem, please provide the full code of your binder/bridge.