[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