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

我们刚刚发布了 Hibernate Search 7.1.0.CR1,这是 Hibernate Search 下一个次要版本的第一个候选版本。

这个版本带来了许多针对独立 POJO 映射器的工作更新和改进,新的查询字符串谓词,并利用 Elasticsearch 8.12 来消除一些向量搜索能力的限制。

新增功能

有关自 7.0 版以来所有新功能和改进的摘要,请访问 hibernate.org 上的专用页面。

依赖升级

Hibernate ORM (HSEARCH-5078)

Hibernate Search 现在依赖于 Hibernate ORM 6.4.4.Final。

Lucene (HSEARCH-5069)

Lucene 后端现在使用 Lucene 9.9.2,它带来了与向量搜索相关的某些错误修复。

Elasticsearch (HSEARCH-5077)

Elasticsearch 后端现在与最新版本的 Elasticsearch 8.12.1 兼容,以及与其他已兼容的版本。

其他

knn 谓词更新

随着 Elasticsearch 8.12 版本的发布,引入了一个新的 knn 查询。此查询与 Hibernate Search 提供的向量搜索功能更一致,并已更新与 Elasticsearch 的集成以使用此新查询。这意味着在使用 Elasticsearch 后端的 Elastic 发行版时对向量搜索施加的先前限制现在已消除。

这意味着在Elasticsearch上现在仅支持Elasticsearch 8.12及更高版本进行向量搜索;Hibernate Search不再支持Elasticsearch 8.11及以下版本的向量搜索。

为了提醒您向量搜索的工作原理:为了使向量字段可以被索引,它们应该使用@VectorField注解进行标记

@Entity
@Indexed
public class Book {

    @Id
    private Integer id;

    @VectorField(dimension = 512)
    private float[] coverImageEmbeddings;

    // Other properties ...
}

然后,通过knn谓词执行向量相似度搜索

float[] coverImageEmbeddingsVector = /*...*/

List<Book> hits = searchSession.search( Book.class )
.where( f ->
    // provide the number of similar documents to look for:
    f.knn( 5 )
        // the name of the vector field:
        .field( "coverImageEmbeddings" )
         // matched documents will be the ones whose indexed vector
         // is "most similar" to this vector
        .matching( coverImageEmbeddingsVector )
).fetchHits( 20 );

请参阅关于向量字段的参考文档以及关于knn谓词的参考文档,获取更多信息。

查询字符串谓词

queryString谓词根据作为字符串给出的结构化查询匹配文档。它允许构建更复杂的查询字符串(使用Lucene的查询语言),并且比simpleQueryString谓词具有更多的配置选项。

List<Book> hits = searchSession.search( Book.class )
    .where( f -> f.queryString().field( "description" )
        .matching( "robots +(crime investigation disappearance)^10 +\"investigation help\"~2 -/(dis)?a[p]+ea?ance/" ) )
    .fetchHits( 20 );

在这个谓词中,查询字符串将导致一个包含4个分句的布尔查询

  • 一个匹配robotsshould分句;

  • 两个must分句

    • (crime || investigation || disappearance)字符串构成的另一个布尔查询,其boost值为10

    • 一个匹配短语investigation help的查询,其短语slop等于2

  • 一个匹配正则表达式(dis)?a[p]+ea?ncemust not分句

    请注意,上述每个分句本身最终可能被转换成其他类型的查询。

请参阅关于queryString谓词的参考文档,获取更多信息。

在独立POJO映射器中进行更简单的实体注册

Hibernate Search简化了定义实体的方法。对于独立映射器,现在只需使用@SearchEntity注解来注解实体即可。

@SearchEntity (1)
// ... Other annotations, e.g. @Indexed if this entity needs to be mapped to an index.
public class Book {

    @Id
    private Integer id;

    // Other properties ...
}
1 使用@SearchEntity注解类型,使其被视为实体。

与此相关的另一个更新是关于如何创建SearchMappingBuilder构建器的方式。现在它需要提供一个注解类型源。

CloseableSearchMapping searchMapping =
SearchMapping.builder( AnnotatedTypeSource.fromClasses( (1)
        Book.class, Associate.class, Manager.class ))
    .property( "hibernate.search.backend.hosts", "elasticsearch.mycompany.com" ) (2)
// ...
    .build(); (3)
1 创建一个构建器,传递一个AnnotatedTypeSource,让Hibernate Search知道在哪里查找注解。

由于类路径扫描,您的AnnotatedTypeSource只需要包含每个包含注解类型的JAR中的一个类。其他类型应自动发现。

2 设置其他配置属性。
3 构建SearchMapping

请参阅关于实体定义的参考文档,获取更多信息。

在独立POJO映射器中通过名称定位实体

独立POJO映射器增加了新的方法,以前仅适用于Hibernate ORM集成,用于从类型名称创建搜索范围。独立POJO映射器的类型名称是在注册实体时使用的名称,无论是通过@SearchEntity(name=…​)注解还是通过使用.searchEntity()的程序定义。

SearchMapping searchMapping = /* ... */ (1)
SearchScope<Book> bookScope = searchMapping.scope( Book.class ); (2)
SearchScope<Person> personSubTypesScope = searchMapping.scope( Person.class,
        List.of( "Manager", "Associate" ) ); (3)
1 检索SearchMapping.
2 使用类创建一个仅针对Book实体类型的SearchScope
3 使用实体名称创建一个仅针对ManagerAssociate子类型的SearchScope

请参阅关于创建搜索范围的方法的参考文档,获取更多信息。

其他改进和错误修复

  • HSEARCH-5020:Hibernate Search 将 Lucene 后端允许的最大向量维度增加到 4096,以允许索引一些模型产生的更长的向量。

  • HSEARCH-5073:现在,Hibernate Search 允许在简单查询谓词上指定 最小-should-match 参数

还有更多。有关自上次发布以来的全部更改列表,请参阅发布说明

如何获取此版本

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

入门,迁移

对于新应用程序,请参阅以下指南以了解 Hibernate ORM 集成

对于现有应用程序,假设您也升级了依赖项,Hibernate Search 7.1 可以直接替换 7.0。有关已弃用的配置和 API 的信息包含在 迁移指南 中。

反馈、问题、想法?

要联系,请使用以下渠道


返回顶部