Hibernate Search is a library that integrates Hibernate ORM with Apache Lucene or Elasticsearch by automatically indexing entities, enabling advanced search functionality: full-text, geospatial, aggregations and more. For more information, see Hibernate Search on hibernate.org.

We just published Hibernate Search 7.1.0.CR1, a first candidate release of the next minor version of Hibernate Search.

This version brings a lot of updates and improvements for working with a Standalone POJO mapper, new query string predicate, and takes advantage of Elasticsearch 8.12 to remove some of the limitations on vector search capabilities.

What’s new

For a summary of all new features and improvements since 7.0, head to the dedicated page on hibernate.org.

Dependency upgrades

Hibernate ORM (HSEARCH-5078)

Hibernate Search now depends on Hibernate ORM 6.4.4.Final.

Lucene (HSEARCH-5069)

The Lucene backend now uses Lucene 9.9.2, which brings some bug fixes related to vector search.

Elasticsearch (HSEARCH-5077)

The Elasticsearch backend now is compatible with Elasticsearch latest 8.12.1 as well as with other versions that were already compatible.

Others

knn predicate updates

With the 8.12 release of Elasticsearch, a new knn query was introduced. This query is more aligned with the vector search capabilities provided by Hibernate Search, and integration with Elasticsearch was updated to use this new query. This means that previous limitations imposed on the vector search when using the Elastic distribution of the Elasticsearch backend are now removed.

It also means that vector search on Elasticsearch is now only available with Elasticsearch 8.12 and later; Hibernate Search no longer supports vector search on Elasticsearch 8.11 and earlier.

To remind how vector search works: for vector fields to be indexed, they should be annotated with a @VectorField annotation:

@Entity
@Indexed
public class Book {

    @Id
    private Integer id;

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

    // Other properties ...
}

Then, searching for vector similarities is performed via a knn predicate:

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

See this section of the reference documentation on vector fields and the one on a knn predicate for more information.

Query string predicate

The queryString predicate matches documents according to a structured query given as a string. It allows building more advanced query strings (using Lucene’s query language) and has more configuration options than a simpleQueryString predicate.

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

The query string, in this predicate, will result in a boolean query with 4 clauses:

  • a should clause matching robots;

  • two must clauses

    • another boolean query constructed from (crime || investigation || disappearance) string with a boost of 10

    • a query matching the phrase investigation help with the phrase slop equals to 2

  • a must not clause matching a regular expression (dis)?a[p]+ea?ance

    Note that each of the mentioned clauses may itself end up being translated into other types of queries.

See this section of the reference documentation on the queryString predicate for more information.

Simpler entity registration in the Standalone POJO mapper

Hibernate Search simplifies how entities can be defined. For standalone mapper now it is enough to annotate your entities with the @SearchEntity annotation.

@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 Annotate the type with @SearchEntity so it is treated as an entity.

Another update related to this is a way the SearchMappingBuilder builder is created. Now it requires an annotated type source to be provided.

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 Create a builder, passing an AnnotatedTypeSource to let Hibernate Search know where to look for annotations.

Thanks to classpath scanning, your AnnotatedTypeSource only needs to include one class from each JAR containing annotated types. Other types should be automatically discovered.

2 Set additional configuration properties.
3 Build the SearchMapping.

See this section of the reference documentation on the entity definition for more information.

Targeting entities by name in the Standalone POJO Mapper

The standalone POJO mapper adds a new way, previously available for Hibernate ORM integration only, for creating a search scope from type names. The type name for the standalone POJO mapper is the name used when registering an entity, be it via the @SearchEntity(name=…​) annotation or through the programmatic definition using .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 Retrieve the SearchMapping.
2 Create a SearchScope targeting only the Book entity type using a class.
3 Create a SearchScope targeting only the Manager and Associate subtypes using their entity names.

See this section of the reference documentation on the ways to create search scope for more information.

Other improvements and bug fixes

  • HSEARCH-5020: Hibernate Search increases the maximum allowed vector dimension for a Lucene backend to 4096 to allow indexing longer vectors produced by some models.

  • HSEARCH-5073: Hibernate Search now allows specifying a minimum-should-match parameter on a simple query predicate.

And more. For a full list of changes since the previous releases, please see the release notes.

How to get this release

All details are available and up to date on the dedicated page on hibernate.org.

Getting started, migrating

For new applications, refer to the getting started guide:

For existing applications, Hibernate Search 7.1 is a drop-in replacement for 7.0, assuming you also upgrade the dependencies. Information about deprecated configuration and API is included in the migration guide.

Feedback, issues, ideas?

To get in touch, use the following channels:


Back to top