[hibernate-dev] [HSEARCH][V6-POC] FieldBridge 2.0

Yoann Rodiere yoann at hibernate.org
Tue Mar 20 03:56:39 EDT 2018


Hello,

In Search 6, we are changing the field bridge APIs to move away from Lucene
dependencies. Similarly to the query DSL, this breaks backward
compatibility whatever we do, so we had a look to improving the field
bridge API a bit with some other changes.

The result is we have three types of bridges:

   - *ValueBridges* can be applied to values, i.e. either a property value
   directly, or container values extracted from the property (list elements,
   map keys, ...). They cannot be parameterized and cannot have dedicated
   annotations (at least for now), and they are applied to a mapping using
   @Field(valueBridge = ...). They are supposed to be applied to simple types
   (LocalDate, some Enum, some immutable user type, ...) and perform a 1-1
   mapping between the value and a *single* index field. Implementations
   are supposed to work as bidirectional functions: one method transforms the
   POJO-side type into the Index-side type, and one method does the opposite.
   - *TypeBridges* can be applied to types, can be parameterized, they each
   have a dedicated annotation (@MyCustomTypeBridge for instance). Their
   implementations are supposed to use specific APIs to access both the
   property values and the index fields, so that Hibernate Search is aware of
   the necessary input data (useful for dirty checking) and of the index
   fields created by the bridge, along with their characteristics (field type,
   stored or not, analyzer, ...).
   - *PropertyBridges* can be applied to properties, can be
   parameterized, they each have a dedicated annotation
   (@MyCustomPropertyBridge for instance). Their implementations are supposed
   to use specific APIs to access both the property values and the index
   fields, so that Hibernate Search is aware of the necessary input data
   (useful for dirty checking) and of the index fields created by the bridge,
   along with their characteristics (field type, stored or not, analyzer, ...).

The expectation is that most users will only need to implement ValueBridge,
which is the simpler one. Users with more advanced needs will be able to
implement TypeBridge/PropertyBridge, which are more complex but are also
much more powerful.

Some aspects of the bridge API are still in the works, so don't be alarmed
to not see them:

   - Access to the type/property data in TypeBridge and PropertyBridge is
   still a bit rough, missing in particular support for container types (List,
   Map, ...).
   - During projections, transforming the projected data using bridges is
   not supported yet.

The showcase contains a few simple bridge implementations.

   - org.hibernate.search.v6poc.integrationtest.showcase.library.bridge.
   *ISBNBridge* is a ValueBridge. Hibernate Search is able to detect from
   its class metadata that it can only be applied to ISBN values, and
   generates a String field.
   The bridge is applied using a @Field annotation
   on org.hibernate.search.v6poc.integrationtest.showcase.library.model.Book#isbn.
   You can find an equivalent use of the bridge in the programmatic mapping
   in org.hibernate.search.v6poc.integrationtest.showcase.library.model.ProgrammaticMappingContributor.
   - Another value bridge is applied
   to org.hibernate.search.v6poc.integrationtest.showcase.library.model.Library#services
   and is implicitly applied to every value of the list.
   - org.hibernate.search.v6poc.integrationtest.showcase.library.bridge.
   *MultiKeywordStringBridge* is a PropertyBridge which turns a
   comma-separated string into multiple field values. It is admittedly a very
   simple PropertyBridge, but it has the advantage of showing pretty clearly
   how a custom bridge is declared and implemented.
   The bridge is applied using its custom "@MultiKeywordStringBridge"
   annotation
   on org.hibernate.search.v6poc.integrationtest.showcase.library.model.Document#tags.
   You can find an equivalent use of the bridge in the programmatic mapping
   in
   org.hibernate.search.v6poc.integrationtest.showcase.library.model.ProgrammaticMappingContributor:
   look for the line where "MultiKeywordStringBridge.Builder" is used.
   - org.hibernate.search.v6poc.entity.pojo.bridge.builtin.spatial.
   *GeoPointBridge* is a more representative example of what an advanced
   bridge could be. It's a built-in bridge, but it could definitely be
   implemented by a third-party: no internal APIs are used in its
   implementation. Note that one characteristic of this field is that it can
   be used both as a TypeBridge or as a PropertyBridge, just as the @Spatial
   annotation in Search 5.
   The bridge is applied using its dedicated "@GeoPointBridge" annotation
   to
   type org.hibernate.search.v6poc.integrationtest.showcase.library.model.Library,
   with "@Latitude" and "@Longitude" annotations on the relevant properties of
   this type.
   You can find an equivalent use of the bridge in the programmatic mapping
   in
   org.hibernate.search.v6poc.integrationtest.showcase.library.model.ProgrammaticMappingContributor:
   look for the line where "GeoPointBridge.Builder" is used, and the lines
   where "LatitudeMarker.Builder" and "LongitudeMarker.Builder" are used.

So, with those few examples of bridges... WDYT?

-- 
Yoann Rodiere
yoann at hibernate.org / yrodiere at redhat.com
Software Engineer
Hibernate NoORM team


More information about the hibernate-dev mailing list