我们刚刚发布了 Hibernate Search 6.2.0.Alpha1,这是 Hibernate Search 下一个次要版本的 alpha 版本。
这个新版本的主要功能是新的独立 POJO 映射器,允许将任意对象映射到索引,即使这些对象不是 Hibernate ORM 实体。这为与您最喜欢的 NoSQL 数据存储的定制集成打开了道路!
除此之外,6.2.0.Alpha1 还包括使用 @ProjectionConstructor 将类/记录映射到投影,搜索 DSL 改进(包括对象字段的投影),与 Elasticsearch 8.3 和 OpenSearch 2.0 的兼容性,以及更多。
感谢
感谢
-
Marko Bekhta 为此版本的功能和错误修复所做的贡献。
-
Waldemar Kłaczyński 在过去一年中为 独立 POJO 映射器 的许多功能奠定了基础。
新增功能
Hibernate Search 6.2 仍在开发中:一些功能可能还不完整或可能以向后不兼容的方式更改。 |
依赖项升级
- Hibernate ORM (HSEARCH-4628/HSEARCH-4627)
-
Hibernate Search 现在依赖于 Hibernate ORM 5.6.10.Final,或 Hibernate ORM 6.1.1.Final 的 -orm6 艺术品。
- Lucene (HSEARCH-4609)
-
Lucene 后端现在使用 Lucene 8.11.2。
- Elasticsearch (HSEARCH-4473/HSEARCH-4622)
-
Elasticsearch 后端现在可以与 Elasticsearch 8.3 和 7.17 以及其他已经兼容的版本一起工作。
- OpenSearch (HSEARCH-4561/HSEARCH-4562)
-
Elasticsearch后端现在也支持OpenSearch 1.3和2.0以及其他已经兼容的版本。
- 其他
-
-
HSEARCH-4631:升级到Elasticsearch 客户端 8.3.2
-
HSEARCH-4485:升级到GSON 2.9.0
-
HSEARCH-4486:升级到slf4j 1.7.36
-
HSEARCH-4539:升级到JBeret 1.4.7.Final
-
HSEARCH-4581:升级到Jackson 2.13.3
-
HSEARCH-4598:升级到Reactive Streams 1.0.4
-
HSEARCH-4608:升级到-orm6/-jakarta工件中Jakarta依赖项的最新版本
-
HSEARCH-4590:升级到-orm6工件中的HCANN 6.0.2
-
独立POJO映射器
独立POJO映射器允许将任意POJO映射到索引中。
与Hibernate ORM集成相比,它的关键特性是可以在没有Hibernate ORM或关系数据库的情况下运行。它可以用于索引来自任意数据存储的实体,甚至(尽管通常不推荐这样做)可以使用Lucene或Elasticsearch作为主数据存储。
有关独立POJO映射器的更多信息,请参阅参考文档的本节。
要开始使用独立POJO映射器,请参阅本入门指南。
将索引内容映射到自定义类型(投影构造函数)
从HSEARCH-3927开始,Hibernate Search现在可以通过映射自定义类型(通常是记录),通过将这些类型或其构造函数应用@ProjectionConstructor
注解来定义投影
@ProjectionConstructor
public record MyBookProjection(String title, List<Author> authors) {
@ProjectionConstructor
public record Author(String firstName, String lastName) {
}
}
执行此类投影现在只需引用自定义类型
List<MyBookProjection> hits = searchSession.search( Book.class )
.select( MyBookProjection.class )
.where( f -> f.matchAll() )
.fetchHits( 20 );
有关更多信息,请参阅参考文档的本节。
映射改进
从HSEARCH-4575开始,所有字段默认可通过Elasticsearch后端进行投影。
进行此更改是因为使字段可投影不会对Elasticsearch后端造成任何性能损失。
由于使字段可投影会对Lucene后端造成性能影响,Lucene后端默认设置没有更改:Lucene字段仍需要显式设置为可投影。
搜索DSL改进
- 复杂、根布尔谓词的更短语法(HSEARCH-4520)
-
现在您可以使用
.where( (f, b) → … )
代替.where( f → f.bool( b → … ) )
MySearchParameters searchParameters = getSearchParameters(); List<Book> hits = searchSession.search( Book.class ) .where( (f, b) -> { b.must( f.matchAll() ); if ( searchParameters.getGenreFilter() != null ) { b.must( f.match().field( "genre" ) .matching( searchParameters.getGenreFilter() ) ); } if ( searchParameters.getFullTextFilter() != null ) { b.must( f.match().fields( "title", "description" ) .matching( searchParameters.getFullTextFilter() ) ); } if ( searchParameters.getPageCountMaxFilter() != null ) { b.must( f.range().field( "pageCount" ) .atMost( searchParameters.getPageCountMaxFilter() ) ); } } ) .fetchHits( 20 );
已弃用较旧的语法,现在使用新的语法。
- 更清晰的复杂、非根布尔谓词的语法(HSEARCH-4520)
-
现在您可以使用
f.bool().with( b → … )
代替f.bool( b → … )
MySearchParameters searchParameters = getSearchParameters(); List<Book> hits = searchSession.search( Book.class ) .where( (f, b) -> { b.must( f.matchAll() ); if ( searchParameters.getGenreFilter() != null ) { b.must( f.match().field( "genre" ) .matching( searchParameters.getGenreFilter() ) ); } if ( !searchParameters.getAuthorFilters().isEmpty() ) { b.must( f.bool().with( b2 -> { for ( String authorFilter : searchParameters.getAuthorFilters() ) { b2.should( f.match().fields( "authors.firstName", "authors.lastName" ) .matching( authorFilter ) ); } } ) ); } } ) .fetchHits( 20 );
已弃用较旧的语法,现在使用新的语法。
- 更清晰的
nested
谓词的语法(HSEARCH-4499) -
现在您可以使用
f.nested( … ).must( … )
代替f.nested().objectField( … ).nest( f.bool().must( … ) )
List<Book> hits = searchSession.search( Book.class ) .where( f -> f.nested( "authors" ) .must( f.match().field( "authors.firstName" ) .matching( "isaac" ) ) .must( f.match().field( "authors.lastName" ) .matching( "asimov" ) ) ) .fetchHits( 20 );
已弃用较旧的语法,现在使用新的语法。
- 新的
matchNone
谓词(HSEARCH-4489) -
matchNone
谓词匹配无文档。List<Book> hits = searchSession.search( Book.class ) .where( f -> f.matchNone() ) .fetchHits( 20 );
- 复合投影的新语法(请参阅此处HSEARCH-4498)
-
现在可以使用流畅的语法定义复合投影
List<MyPair<String, Genre>> hits = searchSession.search( Book.class ) .select( f -> f.composite() .from( f.field( "title", String.class ), f.field( "genre", Genre.class ) ) .as( MyPair::new ) ) .where( f -> f.matchAll() ) .fetchHits( 20 );
大多数较旧的语法已弃用,转而使用新的语法。
- 新的
object
投影(请参阅此处HSEARCH-3943) -
object
投影为给定对象字段中的每个对象返回一个投影值。List<List<MyAuthorName>> hits = searchSession.search( Book.class ) .select( f -> f.object( "authors" ) .from( f.field( "authors.firstName", String.class ), f.field( "authors.lastName", String.class ) ) .as( MyAuthorName::new ) .multi() ) .where( f -> f.matchAll() ) .fetchHits( 20 );
- 新的
constant
投影(请参阅此处HSEARCH-4489) -
constant
投影为每个文档返回相同的值,该值在定义投影时提供。Instant searchRequestTimestamp = Instant.now(); List<MyPair<Integer, Instant>> hits = searchSession.search( Book.class ) .select( f -> f.composite() .from( f.id( Integer.class ), f.constant( searchRequestTimestamp ) ) .as( MyPair::new ) ) .where( f -> f.matchAll() ) .fetchHits( 20 );
outbox-polling
协调改进
自HSEARCH-4533以来,您现在可以通过简单的配置属性自定义 Hibernate Search 的 outbox-polling
协调策略中涉及的表名、模式和目录。
有关更多信息,请参阅参考文档中的此部分。
其他改进和错误修复
-
HSEARCH-4565:现在,对 IndexingDependency(derivedFrom = …) 的循环依赖检测现在可以检测“埋藏”的循环。
-
HSEARCH-4580:自定义 Elasticsearch 模式中不再存在 "_routing",它不会导致“JsonIOException: JSON document was not fully consumed”错误。
-
HSEARCH-4584:现在,Lucene 后端不再因对同一嵌套字段进行投影和排序而失败。
-
HSEARCH-4619:布尔谓词现在在没有任何子句添加的情况下始终与零个文档匹配,无论后端如何。
-
HSEARCH-4604:AWS 请求签名现在不再忽略服务端点的目标端口。
-
HSEARCH-4483:默认的大规模索引监控器(使用日志记录)现在使用不同的格式,并在总体速度之上显示“即时速度”。
-
HSEARCH-4594:现在,配置属性中定义的配置器的 Bean 引用可以是多值的,允许您一次性应用多个配置器。
-
HSEARCH-4611:一些错误消息已得到改进,Hibernate Search 的失败报告中现在对多行错误消息进行了更好的缩进。
等等。有关自上次发布以来的所有更改的完整列表,请参阅发行说明。
如何获取此版本
所有详细信息均可在hibernate.org 上的专用页面上找到并保持最新。
入门,迁移
对于新应用程序,请参阅以下指南:
对于现有应用程序,假设您还升级了依赖项,Hibernate Search 6.2 可作为 6.1 的直接替换。有关已弃用配置和 API 的信息,请参阅迁移指南。