Hibernate Search是一个库,通过自动索引实体,将Hibernate ORM与Apache Lucene或Elasticsearch集成,从而实现高级搜索功能:全文、地理空间、聚合等。更多信息,请参阅hibernate.org上的Hibernate Search。

我们刚刚发布了Hibernate Search 6.0.0.Alpha6,这是仍在开发中的6.0分支的新版本。此版本主要恢复了Lucene索引读写性能,增加了对BigDecimalBigInteger索引的支持,减少了搜索DSL的冗余,并增加了配置自动索引的on-commit同步支持。

开始使用Hibernate Search 6

如果您想直接进入全新的Hibernate Search 6,参考文档中的入门指南是一个很好的起点。

Hibernate Search 6仍在开发中,其API与Search 5有显著差异。

有关此分支的当前状态的更多信息,请参阅hibernate.org上的Search 6专属页面

有关迁移的更多信息以及我们打算如何帮助您,请参阅迁移指南

新功能

Lucene索引访问编排

Lucene后端现在更高效地编排索引读写操作,将这些操作委托给后台线程,就像Search 5中那样。

尽管尚未尝试基准测试,但性能应该会恢复到与Search 5相当的水平。

BigDecimalBigInteger作为缩放数字索引

BigDecimalBigInteger 现在可以使用 Hibernate Search 直接索引。

对于谓词(匹配、范围等)和排序,这些数字将被缩小并作为 long 索引,仅保留最高有效位。

投影不受缩放的影响:对 BigDecimalBigInteger 的投影将返回原始数字,而不仅仅是最高有效位。

默认情况下,缩放值将提取自 Hibernate ORM 的 @Column.scale 属性。您可以使用 Hibernate Search 的 @ScaledNumberField 注解及其 decimalScale 属性来覆盖它。

有关更多信息,请参阅关于 @ScaledNumberField 的文档部分。

搜索 API 改进

搜索 API 再次得到了改进,主要是通过减少其冗余性。

  • .asEntity() 现在可以省略(HSEARCH-3578);

  • .toQuery() 现在可以省略(HSEARCH-3572);

  • 扩展现在可以在 DSL 的开头使用(HSEARCH-3544),并将透明地应用于所有步骤:投影、谓词、排序。

因此,现在可以这样写:

SearchResult<Book> result = Search.getSearchSession(em).search(Book.class)
        .asEntity()
        .predicate(f -> f.extension(ElasticsearchExtension.get()).fromJson("{'match_all': {}}"))
        .sort(f -> f.extension(ElasticsearchExtension.get()).fromJson("{'field1': 'asc'}"))
        .toQuery()
        .fetch(20, 0);

现在可以写成这样:

SearchResult<Book> result = Search.getSearchSession(em).search(Book.class)
        .extension(ElasticsearchExtension.get())
        .predicate(f -> f.fromJson("{'match_all': {}}"))
        .sort(f -> f.fromJson("{'field1': 'asc'}"))
        .fetch(20, 0);

映射 API 改进

HSEARCH-3463 以来,注解映射中指定容器提取器的语法现在更不容易出错,并且更具前瞻性。

简而言之,现在可以这样写:

// Default: automatically resolved
@GenericField
private List<Integer> field1;
// Explicit extractors (built-in)
@GenericField(extractors = @ContainerExtractorRef(BuiltinContainerExtractor.MAP_KEY))
private Map<Integer, String> field2;
// No extractor at all
@GenericField(extractors = {}, valueBridge = @ValueBridgeRef(type = MyOptionalIntBridge.class))
private OptionalInt field3;
// Explicit extractors (builtin, multiple)
@GenericField(extractors = {
        @ContainerExtractorRef(BuiltinContainerExtractor.MAP_KEY),
        @ContainerExtractorRef(BuiltinContainerExtractor.COLLECTION),
}))
private Map<List<Integer>, String> field4;
// Explicit extractors (custom)
@GenericField(extractors = @ContainerExtraction({
        @ContainerExtractorRef(type = MyContainerExtractor.class),
        @ContainerExtractorRef(BuiltinContainerExtractor.COLLECTION)
}))
private MyContainer<List<Integer>> field5;

现在应该这样写:

// Default: automatically resolved
@GenericField
private List<Integer> field1;
// Explicit extractors (built-in)
@GenericField(extraction = @ContainerExtraction(BuiltinContainerExtractors.MAP_KEY))
private Map<Integer, String> field2;
// No extractor at all
@GenericField(extraction = @ContainerExtraction(extract = ContainerExtract.NO))
private OptionalInt field3;
// Explicit extractors (builtin, multiple)
@GenericField(extraction = @ContainerExtraction({
        BuiltinContainerExtractors.MAP_KEY,
        BuiltinContainerExtractors.COLLECTION,
}))
private Map<List<Integer>, String> field4;
// Explicit extractors (custom) => Requires the names to be assigned to classes using a mapping configurer
@GenericField(extraction = @ContainerExtraction({
        "myExtractor1",
        BuiltinContainerExtractors.COLLECTION
}))
private MyContainer<List<Integer>> field5;

自动索引的可配置同步

HSEARCH-3316 中,我们重新设计了自动索引行为的配置方法,特别是 Hibernate Search 在事务提交时等待索引完成的时间。

您现在可以将配置属性 hibernate.search.automatic_indexing.synchronization_strategy 设置为三个值之一:

  • queued 仅将索引任务排队到内存中,而不等待;

  • committed(默认值)等待索引任务被处理并提交到持久存储,然后从数据库提交中返回;

  • searchablecommitted 相同,然后还等待更改在索引中可见,因此数据库提交后立即执行的搜索查询将与提交的事务保持一致,而无需任何进一步的延迟。

每种同步策略都有其优缺点。根据您的应用程序,您可以选择 queued 以提高吞吐量或 searchable 以确保索引在事务提交后始终是最新的。最后一个特别适合自动化测试。

请注意,配置不仅限于这个配置属性:您可以在会话级别覆盖设置(例如,在执行批处理操作时临时将其设置为 queued)或定义自己的自定义策略。

有关更多信息,请参阅关于 自动索引 的文档部分。

搜索命中解释

HSEARCH-3353 以来,Lucene 和 Elasticsearch 查询现在再次公开了 explain() 方法,提供了导致给定文档得分的计算描述。

在查询 DSL 中使用 .extension(LuceneExtension.get()).extension(ElasticsearchExtension.get()) 以检索 LuceneSearchQueryElasticsearchQuery,它们公开了这些 explain() 方法。

有关更多信息,请参阅 LuceneSearchQueryElasticsearchQuery 的 javadoc。

对字节码增强实体的实验性支持

HSEARCH-3581中,我们引入了对从字节码增强实体惰性属性中提取信息实验性支持的。

我们正在寻找反馈:如果您使用字节码增强,请尝试一下,并请告诉我们任何问题。

其他改进和错误修复

  • HSEARCH-3573:将.object()投影重命名为.entity()

  • HSEARCH-3577:由于Lucene和Elasticsearch都不支持它,因此长整型不能再传递给.fetch().fetchHits查询方法,请使用整型代替。

  • HSEARCH-3571:向Elasticsearch发送的请求的语法已经略微改变,以避免在Elasticsearch 6.7及以上版本中出现的警告。

  • HSEARCH-3539:Lucene距离投影现在线程安全。

  • HSEARCH-3324:必须声明多值字段。这只会影响您使用自定义TypeBridgePropertyBridge的情况;否则,Hibernate Search将自动检测多值字段。

  • HSEARCH-3213:在类型级别设置的@Spatial桥不再应用,无论是否有@IndexedEmbedded.includePaths

  • HSEARCH-2663:多值属性的null处理现在与单值属性一致。

  • HSEARCH-1857:如果使用的是其底层ORMSession已关闭的SearchSession,现在将抛出异常。

  • HSEARCH-1645@ProvidedId注解现已正式删除。

等等。有关上一版本以来所有更改的完整列表,请参阅发行说明

如何获取此版本

所有详细信息都可在hibernate.org上的专用页面找到,并且是最新的。

反馈、问题、想法?

要取得联系,请使用以下渠道


回到顶部