我正在使用hibernate search 5.11.1并且需要在String类型的同一字段上支持可搜索和可排序。阅读reference guide后,我找到了有关使用Normalizers对分析文本进行排序的以下文档。
官方指南参考:
当您需要搜索文本文档时,分析器很棒,但如果您想对分析的文本进行排序,该怎么办?然后你遇到了一些麻烦,因为分析的文本是多值的:当标题为“重构:改进现有代码的设计”的书籍时,分析的标题实际上是(无序的)集合{“重构“,”改进“,”设计“,”现有“,”代码“}。如果你在这样的分析之后尝试对标题进行排序,那么任何这些单词都可以被使用,所以你的书可能最终出现在D'(因为“设计”),或者出现在R中(因为“重构”),或在E等等
因此,最后,您可能不希望在对这些字段进行排序时对字段进行标记。规范化器正好解决了这个问题:它们是分析器,但没有标记器,并且有一些运行时检查阻止分析生成多个标记,从而确保您的排序始终保持一致。
Hibernate Search为相关的分析器注释提供了规范化器等效项:@Normalizer,@ NormalizerDef,@ NormalizerDefs。与分析器一样,您可以直接使用实现(例如@Normalizer(impl = MyCollactionKeyAnalyzer.class))或命名规范化器(例如@Normalizer(definition =“myNormalizer”)和@NormalizerDef(filters = @TokenFilterDef(factory = LowerCaseFilterFactory)。类))。
基于以上所述,我编写了以下代码:
@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注释时有效,但在使用两者时都失败。
从错误消息,你似乎写了这样的东西:
qb.sort().byField("orderName").createSort()
但就Hibernate Search而言,字段orderName
并不存在。只有orderName_Search
和orderName_Sort
存在。在这种情况下,你应该写:
qb.sort().byField("orderName_Sort").createSort()
此外,请注意在analyze = Analyze.NO
上设置orderName_Sort
将有效地禁用您的规范化器。你可能想把它留下来。