Hibernate Search

6.2 series development

Standalone POJO Mapper, mapping of classes/records to projections using @ProjectionConstructor, search DSL improvements (including projections on object fields), compatibility with Elasticsearch 8.3 and OpenSearch 2.0.

Compatibility

Java 8, 11, 17 or 18
Hibernate ORM 5.6
Hibernate ORM 6 (through *-orm6 artifacts) 6.1
Elasticsearch server 5.6 - 8.3
OpenSearch server 1.0 - 2.0
Apache Lucene 8.11

Not compatible with your requirements? Have a look at the other series.

See also the Compatibility policy.

Documentation

Documentation for Hibernate Search 6.2 can be accessed through the links below:

HTML PDF API (JavaDoc)

You can find more documentation for all series on the documentation page.

How to get it

Maven, Gradle...

Maven artifacts of Hibernate Search are published to Maven Central and to the JBoss Maven repository. Refer to the Maven Getting Started guide on the JBoss Wiki for more information on how to configure the JBoss Maven repository.

You can find the Maven coordinates of all artifacts through the link below:

Maven artifacts

Below are the Maven coordinates of the main artifacts.

org.hibernate.search:hibernate-search-mapper-orm:6.2.0.Alpha1
Hibernate ORM mapper
org.hibernate.search:hibernate-search-mapper-orm-coordination-outbox-polling:6.2.0.Alpha1
"outbox-polling" coordination strategy for the Hibernate ORM mapper
org.hibernate.search:hibernate-search-mapper-pojo-standalone:6.2.0.Alpha1
Standalone POJO mapper
org.hibernate.search:hibernate-search-backend-lucene:6.2.0.Alpha1
Lucene backend
org.hibernate.search:hibernate-search-backend-elasticsearch:6.2.0.Alpha1
Elasticsearch/OpenSearch backend
org.hibernate.search:hibernate-search-backend-elasticsearch-aws:6.2.0.Alpha1
Amazon IAM authentication for Elasticsearch/OpenSearch
org.hibernate.search:hibernate-search-mapper-orm-batch-jsr352-core:6.2.0.Alpha1
Batch for Java (JSR-352) mass indexing job for the Hibernate ORM mapper - Core
org.hibernate.search:hibernate-search-mapper-orm-batch-jsr352-jberet:6.2.0.Alpha1
Batch for Java (JSR-352) mass indexing job for the Hibernate ORM mapper - JBeret specifics
org.hibernate.search:hibernate-search-v5migrationhelper-orm:6.2.0.Alpha1
Helper for migrating from Hibernate Search 5 to Hibernate Search 6 (Hibernate ORM mapper + Lucene backend)

All Maven artifacts of this project released after 2022-01-26 are signed.

To verify signed Maven artifacts, head to this page.

Zip archive

Direct download is available from SourceForge:

Download Zip archive

More information about specific releases (announcements, download links) can be found here.

Getting started

If you want to start using Hibernate Search 6.2, please refer to the getting started guide:

HTML PDF

Migrating

If you need to upgrade from a previous series, please refer to the migration guide:

HTML PDF

What's new

Hibernate Search 6.2 is still in development:

  • some features may be incomplete;

  • newly introduced features may change in a backward-incompatible way before the stable release.

We encourage you to give it a try and to let us know of any bugs or problems you encounter.

Latest release announcement (2022-07-12): 6.2.0.Alpha1.

A detailed list of new features, improvements and fixes in this series can be found on our issue tracker.

Dependency upgrades

Hibernate ORM

Hibernate Search still depends on Hibernate ORM 5.6, or Hibernate ORM 6.1 for -orm6 artifacts.

Lucene

The Lucene backend still uses Lucene 8.11.

Elasticsearch

The Elasticsearch backend now works with Elasticsearch 8.3 and 7.17 as well as other versions that were already compatible.

OpenSearch

The Elasticsearch backend now works with OpenSearch 1.3 and 2.0 as well as other versions that were already compatible.

Standalone POJO Mapper

The Standalone POJO Mapper enables mapping arbitrary POJOs to indexes.

Its key feature compared to the Hibernate ORM integration is its ability to run without Hibernate ORM or a relational database. It can be used to index entities coming from an arbitrary datastore or even (though that’s not recommended in general) to use Lucene or Elasticsearch as a primary datastore.

For more information about the Standalone POJO Mapper, see this section of the reference documentation.

To get started with the Standalone POJO Mapper, see this getting started guide.

Mapping index content to custom types (projection constructors)

Hibernate Search now offers the ability to define projections through the mapping of custom types (typically records), by applying the @ProjectionConstructor annotation to those types or their constructor:

@ProjectionConstructor
public record MyBookProjection(String title, List<Author> authors) {
    @ProjectionConstructor
    public record Author(String firstName, String lastName) {
    }
}

Executing such a projection then becomes as easy as referencing the custom type:

List<MyBookProjection> hits = searchSession.search( Book.class )
        .select( MyBookProjection.class )
        .where( f -> f.matchAll() )
        .fetchHits( 20 );

Mapping improvements

All fields are now projectable by default with the Elasticsearch backend.

This change was made because making a field projectable doesn’t incur any performance penalty with the Elasticsearch backend.

Since making a field projectable does have an impact on performance with the Lucene backend, the defaults with the Lucene backend didn’t change: Lucene fields still need to be made projectable explicitly.

Search DSL improvements

Shorter syntax for complex, root boolean predicates

Instead of .where( f → f.bool( b → …​ ) ), you can now use .where( (f, 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 );

The older syntax has been deprecated in favor of the new one.

Clearer syntax for complex, non-root boolean predicates

Instead of f.bool( b → …​ ), you can now use f.bool().with( 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 );

The older syntax has been deprecated in favor of the new one.

Clearer syntax for the nested predicate

Instead of f.nested().objectField( …​ ).nest( f.bool().must( …​ ) ), you can now use f.nested( …​ ).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 );

The older syntax has been deprecated in favor of the new one.

New matchNone predicate

The matchNone predicate matches no documents.

List<Book> hits = searchSession.search( Book.class )
        .where( f -> f.matchNone() )
        .fetchHits( 20 );
New syntax for composite projections

The definition of composite projections is now possible with a fluent syntax:

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 );

Most older syntaxes have been deprecated in favor of the new one.

New object projection

The object projection yields one projected value for each object in a given object field.

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 );
New constant projection

The constant projection returns the same value for every single document, the value being provided when defining the projection.

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 coordination improvements

You can now customize table names, schema and catalog involved in Hibernate Search’s outbox-polling coordination strategy through simple, straightforward configuration properties.

Releases in this series

6.2.0.Alpha1

2022-07-12

Standalone POJO Mapper, mapping of classes/records to projections using @ProjectionConstructor, search DSL improvements (including projections on object fields), compatibility with Elasticsearch 8.3 and OpenSearch 2.0, other bugfixes and improvements.

How to get it Getting started

Maven artifacts Download Resolved issues Release announcement

Back to top