Я использую hibernate-поиск 5.11.1, и мне нужно поддерживать поиск и сортировку в одном поле типа String. Прочитав справочное руководство , я нашел следующую документацию по использованию нормализаторов для сортировки анализируемого текста.
Справка из официального руководства:
Анализаторы хороши, когда вам нужно искать в текстовых документах, но
Что делать, если вы хотите отсортировать анализируемый текст? Тогда вы немного
проблемы, потому что анализируемый текст является многозначным: при индексации
книга под названием «Рефакторинг: улучшение дизайна существующих
Код », анализируемый заголовок фактически является (неупорядоченным) набором
{"рефакторинг", "улучшение", "дизайн", "существующий", "код"}. если ты
пытался отсортировать по названию после такого анализа любое из этих слов
может быть использован, так что ваша книга может оказаться в D (из-за
«дизайн»), или в R (из-за «рефакторинга»), или в E,
и т.д.
Итак, в конце концов, вы, вероятно, не хотите, чтобы ваши поля были токенизированы
когда вы сортируете по этим полям. Нормализаторы решают именно эту проблему:
они анализаторы, но без токенизатора и с некоторым временем выполнения
проверки, которые мешают анализу производить несколько токенов, тем самым
гарантируя, что ваши сорта всегда будут последовательными.
Hibernate Search обеспечивает эквивалент нормализатора для соответствующего анализатора
аннотации: @Normalizer, @NormalizerDef, @NormalizerDefs. Как с
анализатор, вы можете использовать реализации напрямую (например,
@Normalizer (impl = MyCollactionKeyAnalyzer.class)) или именованный
нормализаторы (например, @Normalizer (definition = "myNormalizer")
с @NormalizerDef (filters = @TokenFilterDef (factory =
LowerCaseFilterFactory.class)).
Исходя из вышеизложенного, я написал следующий код:
@Entity
@Indexed
@AnalyzerDef(name = "en", tokenizer = @TokenizerDef(factory = StandardTokenizerFactory.class),
filters = {
@TokenFilterDef(factory = LowerCaseFilterFactory.class),
@TokenFilterDef(factory = ASCIIFoldingFilterFactory.class)
})
@NormalizerDef(name = "lowercase", filters = {
@TokenFilterDef(factory = ASCIIFoldingFilterFactory.class),
@TokenFilterDef(factory = LowerCaseFilterFactory.class)
}
)
@Table(name = "ORDER")
public class Order {
//Some other fields that are omitted for brevity here
@Field(name = "orderName_Search", store = Store.YES, analyze = Analyze.YES, analyzer = @Analyzer(definition = "en"))
@Field(name = "orderName_Sort", store = Store.YES, analyze = Analyze.NO, normalizer = @Normalizer(definition = "lowercase"))
@SortableField(forField = "orderName_Sort")
@Column(name = "ORDER_NAME")
private String orderName;
}
Однако, похоже, он не работает, так как я столкнулся со следующей ошибкой.
[ОШИБКА] com.appnexus.konnect.web.exceptions.ConnectExceptionHandler - Исключение
org.hibernate.search.exception.SearchException: невозможно автоматически определить тип поля для поля 'orderName'. Используйте byField (String, Sort.Type), чтобы явно указать тип сортировки
Мой вопрос: где это пошло не так? Работает только при использовании аннотации @Field, но не при использовании обоих.