我们刚刚发布了 Hibernate Search 6.1.0.Alpha1,这是 Hibernate Search 下一个次版本的一个 alpha 版本。
这个新版本的主要功能是一个新的“协调”概念,用于以异步、分布式的方式执行自动索引。它允许实现新的架构,消除了多个不同步索引的风险,并显著减少了在应用线程上自动索引的开销。
除此之外,6.1.0.Alpha1 还包括对 Hibernate ORM、Lucene、Elasticsearch 的新版本的升级,OpenSearch 兼容性,搜索 DSL 的改进,条件批量索引等。
新增功能
Hibernate Search 6.1 还处于开发阶段:一些功能可能还不完整或可能以不兼容的方式更改。 |
依赖升级
- Hibernate ORM (HSEARCH-4279)
-
Hibernate Search 6.1 依赖于 Hibernate ORM 5.5。
- Lucene (HSEARCH-4169)
-
Lucene 后端现在使用 Lucene 8.8。
- Elasticsearch (HSEARCH-4235)
-
Elasticsearch 后端现在支持 Elasticsearch 5.6、6.8 或 7.13。
异步、分布式自动索引
虽然在分布式应用中使用Hibernate Search 6.0和Elasticsearch在技术上可行,但它存在一些局限性。
Hibernate Search 6.1的主要目标是通过引入应用节点之间的协调来消除这些局限性,以实现异步、分布式的自动索引。
在HSEARCH-3280中,我们引入了第一个协调策略;Hibernate Search的后续版本中将会有更多(例如,HSEARCH-3513)。此策略在数据库中创建一个表,将实体更改事件推送到该表,并依赖于后台处理器来消费这些事件并执行自动索引。
除了消除上述局限性外,此策略的另一个优点是Hibernate Search将不再在应用线程中触发延迟加载或构建文档,这可以提高应用的响应速度(在提交时要做的工作更少)。
要在一个单节点应用中直接尝试此策略,只需设置以下属性(您还需要将表添加到您的数据库模式中)
hibernate.search.coordination.strategy = database-polling
对于多节点应用,目前仅支持固定数量的节点,但在6.1.0.Final版本发布之前将支持更动态的设置。有关如何配置协调的更多信息,请参阅文档中的这一部分。
您仍然限于单个应用节点,但您将受益于其他所有优点(数据安全,提高应用响应速度等)。 |
OpenSearch兼容性
自HSEARCH-4212以来,Hibernate Search也与OpenSearch 1.0兼容,这是Elasticsearch的Apache 2.0许可证分支,并定期针对它进行测试。
要使用OpenSearch与Hibernate Search,请使用与Elasticsearch相同的Maven工件、配置和API。
使用Elasticsearch和OpenSearch之间唯一的(较小)区别是如果您显式配置Elasticsearch版本:对于OpenSearch,您需要将版本前缀为opensearch:
,例如opensearch:1.0
。
Search DSL改进
- 新的
terms
谓词 (HSEARCH-2589) -
匹配包含某些术语的文档,可以是任何一个或所有术语。
特别适用于枚举类型的字段。
List<Book> hits = searchSession.search( Book.class ) .where( f -> f.terms().field( "genre" ) .matchingAny( Genre.CRIME_FICTION, Genre.SCIENCE_FICTION ) ) .fetchHits( 20 );
- 新的
regexp
谓词 (HSEARCH-3884) -
匹配包含匹配给定正则表达式的单词的文档。
List<Book> hits = searchSession.search( Book.class ) .where( f -> f.regexp().field( "description" ) .matching( "r.*t" ) ) .fetchHits( 20 );
- 新的
id
投影 (HSEARCH-4142) -
返回匹配实体的标识符。
List<Integer> hits = searchSession.search( Book.class ) .select( f -> f.id( Integer.class ) ) .where( f -> f.matchAll() ) .fetchHits( 20 );
- 可配置的
.missing()
行为用于distance
排序 (HSEARCH-3863) -
现在距离排序允许指定遇到缺失值时的行为(尽管只有
.missing().first()
/.missing().last()
与Elasticsearch一起支持)。GeoPoint center = GeoPoint.of( 47.506060, 2.473916 ); List<Author> hits = searchSession.search( Author.class ) .where( f -> f.matchAll() ) .sort( f -> f.distance( "placeOfBirth", center ) .missing().first() ) .fetchHits( 20 );
- 相对字段路径 (HSEARCH-4245)
-
搜索 DSL 现在允许创建接受相对字段路径的工厂(如
SearchPredicateFactory
等)。这在将工厂传递给可重用方法时非常有用。
List<Book> hits = searchSession.search( Book.class ) .where( f -> f.bool() .should( f.nested().objectField( "writers" ) .nest( matchFirstAndLastName( f.withRoot( "writers" ), "bob", "kane" ) ) ) .should( f.nested().objectField( "artists" ) .nest( matchFirstAndLastName( f.withRoot( "artists" ), "bill", "finger" ) ) ) ) .fetchHits( 20 ); private SearchPredicate matchFirstAndLastName(SearchPredicateFactory f, String firstName, String lastName) { return f.bool() .must( f.match().field( "firstName" ) .matching( firstName ) ) .must( f.match().field( "lastName" ) .matching( lastName ) ) .toPredicate(); }
条件批量索引
HSEARCH-499 引入了根据 HQL/JPQL 的 "where" 子句将批量索引器应用于实体子集的能力,具体请参阅 批量索引器应用文档。
SearchSession searchSession = Search.session( entityManager );
MassIndexer massIndexer = searchSession.massIndexer();
massIndexer.type( Book.class ).reindexOnly( "e.publicationYear <= 2100" );
massIndexer.type( Author.class ).reindexOnly( "e.birthDate < :birthDate" )
.param( "birthDate", LocalDate.ofYearDay( 2100, 77 ) );
massIndexer.startAndWait();
命名谓词
HSEARCH-3325 添加了 命名谓词,这是一种在自定义绑定器/桥接器中定义搜索逻辑的方式。
这某种程度上是 Hibernate Search 5 中的 "全文过滤器" 的回归。
感谢 Waldemar Kłaczyński 对此功能所做的贡献!
自定义 ES 索引设置
自 HSEARCH-3934 以来,您可以为 Hibernate Search 提供包含所需索引设置的 JSON 文件,并将在创建/更新索引时自动推送这些设置。
# To configure the defaults for all indexes:
hibernate.search.backend.schema_management.settings_file = custom/index-settings.json
# To configure a specific index:
hibernate.search.backend.indexes.<index name>.schema_management.settings_file = custom/index-settings.json
访问 Lucene 的 IndexReader
多亏了 HSEARCH-4065,现在在使用 Lucene 后端时,您可以检索 IndexReader。
SearchMapping mapping = Search.mapping( entityManagerFactory );
LuceneIndexScope indexScope = mapping
.scope( Book.class ).extension( LuceneExtension.get() );
try ( IndexReader indexReader = indexScope.openIndexReader() ) {
// work with the low-level index reader:
numDocs = indexReader.numDocs();
}
虽然通常不是必需的,但这对于高级、低级操作非常有用。
Lucene 低级命中缓存
自 HSEARCH-3880 以来,Hibernate Search 允许在 Lucene 后端中配置 QueryCache 和 QueryCachingPolicy,为高级 Lucene 用户添加了一个性能微调。
感谢 Waldemar Kłaczyński 对此功能所做的贡献!
其他改进和错误修复
-
HSEARCH-2599:现在可以通过专用 API 对 Elasticsearch 的 HTTP 客户端配置进行 自定义。
-
HSEARCH-3608:现在可以将绑定器(桥接器)传递给 简单的字符串参数,这些参数不需要自定义注解。
-
HSEARCH-3771:批量索引现在支持 Hibernate ORM 的动态映射实体类型。
-
HSEARCH-3878:批量索引现在最大化了数据库连接的利用率,在相同数量的连接上执行了多达两倍的加载。
请注意,吞吐量不会翻倍,因为存在其他瓶颈,但 它可能会略有提升。
-
HSEARCH-4138,HSEARCH-4139:对自动索引进行了各种性能改进。
-
HSEARCH-4148:现在可以将
@IndexingDependency(derivedFrom = …)
应用于实体类型上的抽象方法实现。 -
HSEARCH-4163:多租户不再需要显式设置。
-
HSEARCH-4303:在适当的条件下,现在将触发包含实体的重新索引,即使包含实体中没有相应的更新,就像在 Hibernate Search 5 中一样。
还有更多。有关自上次发布以来的完整更改列表,请参阅 发布说明。
如何获取此版本
所有详细信息均可在hibernate.org上的专属页面找到,并且都是最新的。