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

我们很高兴宣布发布 Hibernate Search 7.1.0.Final。

与 Hibernate Search 7.0 相比,此版本引入了向量搜索功能,允许查找元模型中每个字段的特性,添加了一个新的查询字符串谓词,简化了独立 POJO 映射器中的实体注册,增加了与 Elasticsearch 8.12 和 OpenSearch 2.12 的兼容性,升级到 Lucene 9.9,并带来了其他错误修复和改进。

与 Hibernate Search 7.0 相比的新功能

依赖项升级

Lucene

Lucene 后端现在使用 Lucene 9.9。除了其他改进外,它还带来了更好的向量搜索性能。

Elasticsearch

Elasticsearch 后端与 Elasticsearch 8.12 以及其他已兼容的版本一起工作。

OpenSearch

Elasticsearch 后端与 OpenSearch 2.12 以及其他已兼容的版本一起工作。

Hibernate Search 现在允许 Lucene 和 Elasticsearch 后端进行向量搜索,这是一个孵化功能。向量搜索提供了在二进制(图像、音频或视频)或文本数据上搜索的工具:外部工具将这些数据转换为向量(字节数组或浮点数数组,也称为“嵌入”),然后用于 Hibernate Search 中的索引和查询。Hibernate Search 引入了一个新的字段类型 @VectorField 和一个新的谓词 knn,以便向量可以索引并搜索。

向量场可以与文档中表示为 bytefloat 数组的向量数据一起工作。默认情况下,byte[]float[] 属性类型将与新的字段类型一起工作。对于任何其他实体属性类型,应实现自定义的 值桥值绑定器。请注意,索引向量 必须 具有相同的长度,并且应该在创建模式之前指定此长度

@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 )
    // additionally an optional filter can be supplied
    // to provide a regular fulltext search predicate
    .filter( f.match().field( "authors.firstName" ).matching( "arthur" ) )
).fetchHits( 20 );

请注意,每个后端在向量搜索方面可能有自己的特定性和限制。有关更多详细信息,请参阅相关的 文档

在元模型中查找每个字段的特性

现在,在检查元模型时,可以查看哪些特性(谓词/排序/投影等)对字段可用

SearchMapping mapping = /*...*/ ;
// Retrieve a SearchIndexedEntity:
SearchIndexedEntity<Book> bookEntity = mapping.indexedEntity( Book.class );
// Get the descriptor for that index.
// The descriptor exposes the index metamodel:
IndexDescriptor indexDescriptor = bookEntity.indexManager().descriptor();

// Retrieve a field by name
// and inspect its capabilities if such field is present:
indexDescriptor.field( "releaseDate" ).ifPresent( field -> {
        if ( field.isValueField() ) {
                // Get the descriptor for the field type:
                IndexValueFieldTypeDescriptor type = field.toValueField().type();
                // Inspect the "traits" of a field type:
                // each trait represents a predicate/sort/projection/aggregation
                // that can be used on fields of that type.
                Set<String> traits = type.traits();
                if ( traits.contains( IndexFieldTraits.Aggregations.RANGE ) ) {
                        // ...
                }
                if ( traits.contains( IndexFieldTraits.Predicates.EXISTS ) ) {
                        // ...
                }
                // ...
        }
} );

查询字符串谓词

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) 字符串构成的布尔查询,其提升值为 10

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

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

    请注意,每个提到的子句本身也可能被转换为其他类型的查询。

有关 queryString 谓词 的更多信息,请参阅参考文档的此部分。

在 Standalone 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

有关更多信息,请参阅参考文档的 实体定义 部分。

与 Hibernate Search 7.0.0.CR1 相比的新功能

  • HSEARCH-5083:升级到 AWS SDK 2.24.1。

  • HSEARCH-5091:升级到 Elasticsearch 客户端 8.12.2。

  • HSEARCH-5087:添加对 OpenSearch 2.12.0 的兼容性。

  • HSEARCH-5039:修复了需要多租户过滤器的问题。

  • HSEARCH-5088:限制OpenSearch向量化搜索功能到2.9+版本。虽然OpenSearch的早期版本已经引入了向量化搜索功能,但2.9版本是首次引入所有集成所需功能的第一个版本。

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

如何获取此版本

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

入门,迁移

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

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

反馈,问题,想法?

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


回到顶部